0
点赞
收藏
分享

微信扫一扫

单向链表模版实现(c++)

小沙坨 03-17 06:30 阅读 2

关于单向链表

单向链表是链表最常用的一种,一个列表节点有两个字段,即数据域和指针域。在单向链表中,指向第一个节点的节点称为“头结点”,最后一个节点的指针域设为null。
在这里插入图片描述
如图即是{1,3,1,4,5,2,1}存在在单向链表的示意图,头节点数据域为null,指向首节点(数据域为1),首节点指向下一个节点,一直到最后一个节点,指向null。1部分是3部分的前驱节点,3部分是1部分的后驱节点。

1.已知列表的每一个节点有数据域和指针域组成,故定义一个节点结构体ListNode:

struct ListNode{
	eleType data;
	ListNode *next;
	ListNode(eleType ele) : data(ele), next(nullptr) {}
};

解释: data表示数据域,*next表示下一个节点(后继节点)。ListNode(eleType ele) : data(ele), next(nullptr) {}构造函数,在声明节点对象的时候,将ele赋值给data,next节点设置为空。

2.接下来建立一个链表类LinkedList:

class LinkedList{
private:
	ListNode *head;
	int size;
public:
	LinkedList() : head(nullptr), size(0) {}
	~LinkedList();
	//增删改查
	void insertToIndex(int index,eleType element); //增
	void removeByIndex(int index); //删
	ListNode* getListNodeByIndex(int index); //改
	void updateListNodeByIndex(int index,eleType value); //差
	void printList(); //打印
};

解释: 该类有两个私有成员,*head表示头节点,size表示链表长度,在构造函数中分别初始化为null和0,表示是一个空表。定义了析构函数,在后面实现。另声明了该类的增删改查函数。

3.实现析构函数,在销毁链表时调用:

/*定义一个游标节点,从头节点出发,遍历,赋值给tmp,执行删除*/
   LinkedList::~LinkedList(){
	ListNode *curr = head;
	while (curr != nullptr) {
		ListNode *tmp = curr;
		curr = curr->next;
		delete tmp;
	}
}     

4.插入函数实现

void LinkedList::insertToIndex(int index, eleType element){
	if(index < 0 || index > size)
		throw out_of_range("Invalid position");
	ListNode *newNode = new ListNode(element);
	if(index == 0){
		newNode->next = head;
		head = newNode;
	}else{
		ListNode *curr = head;
		for(int i = 0; i < index - 1; ++ i){
			curr = curr->next;
		}
		newNode->next = curr->next;
		curr->next = newNode;
	}
	++ size;
}		

解释: 传入index以及要插入的元素,首先进行下表越界判断,抛出异常。之后通过ListNode创建一个新节点,如果要插入位置为头节点,就让新节点指向头节点,将头节点赋值给新节点。如果插入位置不是头节点,则建立一个游标节点curr,循环遍历至要插入的位置的前一个节点,之后把新节点指向这个位置的后一个节点,再让这个位置的后继节点等于新节点。最后size加一。

5.删除函数实现

void LinkedList::removeByIndex(int index){
	if(index < 0 || index > size)
		throw out_of_range("Invalid position");
	ListNode *curr = head;
	for(int i = 0; i < index - 1; ++ i){
		curr = curr->next;
	}
	ListNode *temp = curr->next;
	curr->next = temp->next;
	delete temp;
}

解释: 传入index表示要删除节点的位置,首先进行下表合法校验。之后同样建立游标节点,遍历至要删除位置的前一个节点,然后建立一个临时节点保存要删除的节点,在让curr的后继节点指向tmp的后继节点,之后删除tmp。

5.查找函数实现

	ListNode*  LinkedList::getListNodeByIndex(int index){
	if(index < 0 || index > size)
		throw out_of_range("Invalid position");
	ListNode *curr = head;
	for(int i = 0; i < index;i++){
		curr = curr->next;
	}
	return curr;
}

解释 该函数返回的是一个节点类型,首先进行下表判断,之后遍历至要返回的位置,返回该节点即可。

6.修改函数实现

void LinkedList::updateListNodeByIndex(int index,eleType value){
	if(index < 0 || index > size)
		throw out_of_range("Invalid position");
	getListNodeByIndex(index)->data = value;
};

解释该函数返回值为空,直接调用查找函数找到对应节点,之后修改其指针域为对应值即可。

主函数测试

	int main(){
	LinkedList list;
	list.insertToIndex(0, 33);
	list.insertToIndex(1, 33);
	list.insertToIndex(2, 33);
	list.updateListNodeByIndex(2, 66);
	//list.removeByIndex(0);
	list.printList();
	cout<<list.getListNodeByIndex(0)->data;
}
/*
结果:
33 33 66 
---------------------
33
*/
完整程序
#include <iostream>
#include<stdexcept>
using namespace std;

#define  eleType int

struct ListNode{
	eleType data;
	ListNode *next;
	
	ListNode(eleType ele) : data(ele), next(nullptr) {}
};
class LinkedList{
private:
	ListNode *head;
	int size;
public:
	LinkedList() : head(nullptr), size(0) {}
	~LinkedList();
	void insertToIndex(int index,eleType element);
	void removeByIndex(int index);
	ListNode* getListNodeByIndex(int index);
	void updateListNodeByIndex(int index,eleType value);
	void printList();
};
LinkedList::~LinkedList(){
	ListNode *curr = head;
	while (curr != nullptr) {
		ListNode *tmp = curr;
		curr = curr->next;
		delete tmp;
	}
}
void LinkedList::insertToIndex(int index, eleType element){
	if(index < 0 || index > size)
		throw out_of_range("Invalid position");
	ListNode *newNode = new ListNode(element);
	if(index == 0){
		newNode->next = head;
		head = newNode;
	}else{
		ListNode *curr = head;
		for(int i = 0; i < index - 1; ++ i){
			curr = curr->next;
		}
		newNode->next = curr->next;
		curr->next = newNode;
	}
	++ size;
}
void LinkedList::removeByIndex(int index){
	if(index < 0 || index > size)
		throw out_of_range("Invalid position");
	ListNode *curr = head;
	for(int i = 0; i < index - 1; ++ i){
		curr = curr->next;
	}
	ListNode *temp = curr->next;
	curr->next = temp->next;
	delete temp;
}
	ListNode*  LinkedList::getListNodeByIndex(int index){
		if(index < 0 || index > size)
			throw out_of_range("Invalid position");
		ListNode *curr = head;
		for(int i = 0; i < index;i++){
			curr = curr->next;
		}
		return curr;
	}
void LinkedList::updateListNodeByIndex(int index,eleType value){
	if(index < 0 || index > size)
		throw out_of_range("Invalid position");
	getListNodeByIndex(index)->data = value;
};

void LinkedList::printList(){
	ListNode *curr = head;
	while (curr != nullptr) {
		cout<<curr->data<<' ';
		curr = curr->next;
	}
	cout<<"\n---------------------\n";
}
int main(){
	LinkedList list;
	list.insertToIndex(0, 33);
	list.insertToIndex(1, 33);
	list.insertToIndex(2, 33);
	list.updateListNodeByIndex(2, 66);
	//list.removeByIndex(0);
	list.printList();
	cout<<list.getListNodeByIndex(0)->data;
}
举报

相关推荐

0 条评论