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

关于单向链表

单向链表是链表最常用的一种,一个列表节点有两个字段,即数据域和指针域。在单向链表中,指向第一个节点的节点称为"头结点",最后一个节点的指针域设为null。

如图即是{1,3,1,4,5,2,1}存在在单向链表的示意图,头节点数据域为null,指向首节点(数据域为1),首节点指向下一个节点,一直到最后一个节点,指向null。1部分是3部分的前驱节点,3部分是1部分的后驱节点。

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

c 复制代码
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:

c 复制代码
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.实现析构函数,在销毁链表时调用:

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

4.插入函数实现

c 复制代码
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.删除函数实现

c 复制代码
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.查找函数实现

c 复制代码
	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.修改函数实现

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

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

主函数测试

c 复制代码
	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
*/
完整程序
c 复制代码
#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;
}
相关推荐
不忘不弃1 分钟前
用BFS方法求解平分汽油问题
算法·宽度优先
AI科技星14 分钟前
全域数学·72分册·射影原本 无穷维射影几何卷细化子目录【乖乖数学】
人工智能·线性代数·算法·机器学习·数学建模·数据挖掘·量子计算
风落无尘22 分钟前
《智能重生:从垃圾堆到AI工程师》——第四章 变化的艺术
人工智能·线性代数·算法
JAVA面经实录91728 分钟前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
特种加菲猫39 分钟前
继承,一场跨越时空的对话
开发语言·c++
AC赳赳老秦40 分钟前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
WBluuue1 小时前
Codeforces 1093 Div2(ABCD1D2)
c++·算法
浅念-1 小时前
「一文吃透 BFS:从层序遍历到锯齿形、最大宽度、每层最大值」
数据结构·算法
汉克老师1 小时前
GESP5级C++考试语法知识(十三、贪心算法(一))
算法·贪心算法·海盗船·gesp5级·gesp五级·排队接水
玩转单片机与嵌入式2 小时前
玩转边缘AI(TInyML):需要掌握的C++知识汇总!
开发语言·c++·人工智能