1.单向链表
头节点不存储信息,尾节点存储信息,便于后续尾插
//单链表
class List
{
private:
struct Node
{
int value;
Node* next;
};
//头节点,不存储信息
Node* head;
//尾结点,便于后续尾插
Node* tail;
//数量
int size;
public:
List()
{
this->head = new Node;
//开始时,head和tail重合
this->tail = this->head;
this->head->next = nullptr;
this->size = 0;
}
//尾插
void push_back(int data)
{
Node* pnew = new Node;
pnew->value = data;
pnew->next = nullptr;
this->tail->next = pnew;
this->tail = pnew;
this->size++;
}
//尾删
void pop_back()
{
//判断链表是否为空
if (this->size == 0)
return;
//temp用于记录尾节点的前一个节点
Node* temp = this->head;
Node* del = this->head->next;
while (del)
{
temp = del;
del = del->next;
}
delete del;
temp->next = nullptr;
//删除del后,temp为尾结点,故tail指向temp
this->tail = temp;
this->size--;
}
//插入
void Insert(int n, int data)
{
if (n<0 || n>this->size)
return;
else if (n == this->size)//插入到尾部
{
this->push_back(data);
return;
}
else if (n == 0)//插入到头部
{
Node* pnew = new Node;
pnew->value = data;
pnew->next = this->head->next;
this->head->next = pnew;
}
else//插入到其他位置
{
Node* temp = this->head->next;
for (int i = 1; i < n; i++)
temp = temp->next;
Node* pnew = new Node;
pnew->value = data;
pnew->next = temp->next;
temp->next = pnew;
}
this->size++;
}
//删除
void Delete(int n)
{
if (n < 0 || n >= this->size)
return;
else if (n == this->size - 1)//尾删
{
this->pop_back();
return;
}
else if (n == 0)//头删
{
Node* del = this->head->next;
this->head->next = del->next;
delete del;
}
else//删除其他节点
{
Node* temp = this->head->next;
for (int i = 1; i < n; i++)
temp = temp->next;
Node* del = temp->next;
temp->next = del->next;
delete del;
}
this->size--;
}
//遍历链表
void Travel()
{
Node* temp = this->head->next;
while (temp)
{
cout << temp->value << " ";
temp = temp->next;
}
cout << endl;
}
//链表反转
void Reserve()
{
if (this->size <= 1)
return;
//当前节点要指向的新节点
Node* pre = nullptr;
//当前节点的下一个节点
Node* temp = nullptr;
//当前节点
Node* cur = this->head->next;
Node* flag = cur;
while (cur)
{
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
this->head->next = pre;
this->tail = flag;
}
~List()
{
Node* temp = this->head->next;
while (temp)
{
this->head->next = temp->next;
delete temp;
temp = this->head->next;
}
delete this->head;
}
};
2.双向链表
head和tail都不存储信息,只用于指向作用
//双向链表
class DList
{
private:
struct DNode
{
int value;
DNode* next;
DNode* prev;
};
//头结点
DNode* head;
//尾节点
DNode* tail;
int size;
public:
DList()
{
//头结点和尾节点都不存储信息,只用于指向作用
this->head = new DNode;
this->tail = new DNode;
this->head->next = this->tail;
this->tail->prev = this->head;
this->head->prev = this->tail;
this->tail->next = nullptr;
this->size = 0;
}
//尾插
void push_back(int data)
{
DNode* pnew = new DNode;
pnew->value = data;
//先将新节点的指向弄好
pnew->next = this->tail;
pnew->prev = this->tail->prev;
//再更新旧节点的指向
this->tail->prev->next = pnew;
this->tail->prev = pnew;
this->size++;
}
//尾删
void pop_back()
{
if (this->size == 0)
return;
DNode* del = this->tail->prev;
//更新节点指向
del->prev->next = this->tail;
this->tail->prev = del->prev;
//删除节点
delete del;
this->size--;
}
//插入
void Insert(int n, int data)
{
if (n<0 || n>this->size)
return;
else if (n == this->size)//尾插
{
this->push_back(data);
return;
}
else if (n == 0)//头插
{
DNode* pnew = new DNode;
pnew->value = data;
pnew->prev = this->head;
pnew->next = this->head->next;
this->head->next->prev = pnew;
this->head->next = pnew;
}
else//插入到其他位置
{
DNode* pnew = new DNode;
pnew->value = data;
//根据插入位置分成两种情况插入,以提高插入速度
if (n <= this->size / 2)
{
DNode* temp = this->head->next;
for (int i = 1; i < n; i++)
temp = temp->next;
pnew->next = temp->next;
pnew->prev = temp;
temp->next->prev = pnew;
temp->next = pnew;
}
else
{
DNode* temp = this->tail->prev;
for (int i = 1; i < this->size - n; i++)
temp = temp->prev;
pnew->prev = temp->prev;
pnew->next = temp;
temp->prev->next = pnew;
temp->prev = pnew;
}
}
this->size++;
}
//删除
void Delete(int n)
{
if (n < 0 || n >= this->size)
return;
else if (n == this->size - 1)//尾删
{
this->pop_back();
return;
}
else if (n == 0)//头删
{
DNode* del = this->head->next;
del->next->prev = this->head;
this->head->next = del->next;
delete del;
}
else//删除其他节点
{
//根据删除位置分成两种情况删除,提高删除速度
if (n <= this->size / 2)
{
DNode* temp = this->head->next;
for (int i = 1; i < n; i++)
temp = temp->next;
DNode* del = temp->next;
del->next->prev = temp;
temp->next = del->next;
delete del;
}
else
{
DNode* temp = this->tail->prev;
for (int i = 1; i < this->size - n; i++)
temp = temp->prev;
DNode* del = temp->prev;
del->prev->next = temp;
temp->prev = del->prev;
delete del;
}
}
this->size--;
}
//遍历
void Travel()
{
DNode* temp = this->head->next;
while (temp != this->tail)
{
cout << temp->value << " ";
temp = temp->next;
}
cout << endl;
}
~DList()
{
DNode* temp = this->head->next;
while (temp != this->tail)
{
this->head->next = temp->next;
delete temp;
temp = this->head->next;
}
//删除头结点和尾节点
delete this->head;
delete this->tail;
}
};
3.循环链表
head不存储信息,只用于指向作用
//循环链表
//循环链表声明
template<typename T>
class CList;
//循环节点声明
template<typename T>
class CNode
{
//将循环链表作为其友元类
friend class CList<T>;
private:
CNode* prev;
CNode* next;
//注意,如果T是自定义类型,还需要为T类型重载==运算符,以便后续的链表查找操作
T value;
};
//循环链表定义
template<typename T>
class CList
{
private:
//循环链表头指针,头指针不储存信息
CNode<T>* head;
int size;
public:
CList()
{
this->head = new CNode<T>;
this->head->next = this->head->prev = this->head;
this->size = 0;
}
//尾插
void push_back(const T& data)
{
CNode<T>* pnew = new CNode<T>;
pnew->value = data;
//先设置好新节点指向
pnew->prev = this->head->prev;
pnew->next = this->head;
//更新其他节点指向
this->head->prev->next = pnew;
this->head->prev = pnew;
this->size++;
}
//尾删
void pop_back()
{
if (this->size == 0)
return;
CNode<T>* del = this->head->prev;
//更新其他节点指向
this->head->prev = del->prev;
del->prev->next = this->head;
//删除节点
delete del;
this->size--;
}
//插入
void Insert(int n, const T& data)
{
if (n<0 || n>this->size)
return;
else if (n == this->size)//尾插
{
this->push_back(data);
return;
}
else if (n == 0)//头插
{
CNode<T>* pnew = new CNode<T>;
pnew->value = data;
pnew->next = this->head->next;
pnew->prev = this->head;
this->head->next->prev = pnew;
this->head->next = pnew;
}
else//插入到其他位置
{
CNode<T>* pnew = new CNode<T>;
pnew->value = data;
//根据插入位置分为不同插入情况
if (n <= this->size / 2)
{
CNode<T>* temp = this->head->next;
for (int i = 1; i < n; i++)
temp = temp->next;
pnew->next = temp->next;
pnew->prev = temp;
temp->next->prev = pnew;
temp->next = pnew;
}
else
{
CNode<T>* temp = this->head->prev;
for (int i = 1; i < this->size - n; i++)
temp = temp->prev;
pnew->prev = temp->prev;
pnew->next = temp;
temp->prev->next = pnew;
temp->prev = pnew;
}
}
this->size++;
}
//删除
void Delete(int n)
{
if (n < 0 || n >= this->size)
return;
else if (n == this->size - 1)//尾删
{
this->pop_back();
return;
}
else if (n == 0)//头删
{
CNode<T>* temp = this->head->next;
temp->next->prev = this->head;
this->head->next = temp->next;
delete temp;
}
else//删除其他位置
{
//根据删除位置分为两种删除情况,提高删除效率
if (n <= this->size / 2)
{
CNode<T>* temp = this->head->next;
for (int i = 1; i < n; i++)
temp = temp->next;
CNode<T>* del = temp->next;
temp->next = del->next;
del->next->prev = temp;
delete del;
}
else
{
CNode<T>* temp = this->head->prev;
for (int i = 1; i < this->size - n; i++)
temp = temp->prev;
CNode<T>* del = temp->prev;
temp->prev = del->prev;
del->prev->next = temp;
delete del;
}
}
this->size--;
}
//遍历
void Travel()
{
CNode<T>* temp = this->head->next;
while (temp != this->head)
{
cout << temp->value << " ";
temp = temp->next;
}
cout << endl;
}
~CList()
{
CNode<T>* temp = this->head->next;
while (temp != this->head)
{
this->head->next = temp->next;
delete temp;
temp = this->head->next;
}
//删除头结点
delete this->head;
}
};
4.静态链表
//静态链表
class SList
{
private:
//静态节点
struct SNode
{
//值
int value;
//下一个节点的序号
int next;
//上一个节点的序号
int pre;
};
//节点数组
SNode arr[1000];
//链表起始节点的序号
int start;
//当前链表的最后一个节点的序号
int end;
//链表的下一个节点序号
int next;
//记录节点个数
int size;
public:
SList()
{
//初始化节点数组
for (int i = 0; i < 1000; i++)
{
arr[i].next = i + 1;
arr[i].pre = i - 1;
}
//开始时,start,end,next都指向0
this->start = 0;
this->end = 0;
this->next = 0;
this->size = 0;
//最后一个节点的下一个节点为-1,代表此时数组已满
arr[999].next = -1;
}
//尾插
void push_back(int data)
{
if (this->next == -1)
return;
arr[next].value = data;
//更新end和next
this->end = next;
this->next = arr[next].next;
this->size++;
}
//尾删
void pop_back()
{
if (this->size == 0)
return;
//更新next和end
this->next = this->end;
this->end = arr[this->end].pre;
this->size--;
}
//插入
void Insert(int n,int data)
{
if (n<0 || n>this->size)
return;
else if (n == this->size)//尾插
{
this->push_back(data);
return;
}
else if (n == 0)//头插
{
//记录当前的next值
int temp = this->next;
//更新end节点指向
arr[this->end].next = arr[temp].next;
arr[arr[temp].next].pre = this->end;
//更新next值
this->next = arr[temp].next;
arr[temp].value = data;
//更新start和temp指向
arr[temp].next = this->start;
arr[this->start].pre = temp;
arr[temp].pre = -1;
//更新start
this->start = temp;
}
else//插入到其他位置
{
//记录当前next
int temp = this->next;
int ans = this->start;
for (int i = 1; i < n; i++)
ans = this->arr[ans].next;
//更新end指向
arr[this->end].next = arr[temp].next;
arr[arr[temp].next].pre = this->end;
//更新next
this->next = arr[temp].next;
//更新temp指向
arr[temp].value = data;
arr[temp].pre = ans;
arr[temp].next = arr[ans].next;
arr[arr[ans].next].pre = temp;
arr[ans].next = temp;
}
this->size++;
}
//删除
void Delete(int n)
{
if (n < 0 || n >= this->size)
return;
else if (n == this->size - 1)//尾删
{
this->pop_back();
return;
}
else if (n == 0)//头删
{
//记录删除节点索引
int del = this->start;
//更新start
this->start = arr[del].next;
arr[this->start].pre = -1;
//更新next
this->next = del;
//更新del指向
arr[del].next = arr[this->end].next;
arr[del].pre = this->end;
arr[arr[this->end].next].pre = del;
arr[this->end].next = del;
//更新next
this->next = del;
}
else//删除其他位置
{
int ans = this->start;
for (int i = 1; i < n; i++)
ans = arr[ans].next;
//记录删除节点索引
int del = arr[ans].next;
//更新节点指向
arr[ans].next = arr[del].next;
arr[arr[del].next].pre = ans;
//更新next
this->next = del;
//更新next指向
arr[del].next = arr[this->end].next;
arr[del].pre = this->end;
arr[arr[this->end].next].pre = del;
arr[this->end].next = del;
//更新next
this->next = del;
}
this->size--;
}
//遍历
void Travel()
{
int n = this->start;
for (int i = 0; i < this->size; i++)
{
cout << arr[n].value << " ";
n = arr[n].next;
}
cout << endl;
}
};
5.测试代码
//单链表的测试代码
void testList()
{
List list;
for (int i = 0; i < 5; i++)
list.push_back(i * 10);
list.Travel();
list.Insert(0, 50);
list.Insert(6, 60);
list.Insert(3, 70);
list.Travel();
list.Reserve();
list.Travel();
list.pop_back();
list.pop_back();
list.Travel();
list.Delete(0);
list.Delete(4);
list.Delete(2);
list.Travel();
}
//双链表的测试代码
void testDList()
{
DList list;
for (int i = 0; i < 5; i++)
list.push_back(i * 10);
list.Travel();
list.Insert(0, 50);
list.Insert(6, 60);
list.Insert(3, 70);
list.Travel();
list.pop_back();
list.pop_back();
list.Travel();
list.Delete(0);
list.Delete(3);
list.Delete(2);
list.Travel();
}
//循环链表的测试代码
void testCList()
{
CList<int>list;
for (int i = 0; i < 5; i++)
list.push_back(i * 10);
list.Travel();
list.Insert(0, 50);
list.Insert(6, 60);
list.Insert(3, 70);
list.Travel();
list.pop_back();
list.pop_back();
list.Travel();
list.Delete(0);
list.Delete(3);
list.Delete(2);
list.Travel();
}
//静态链表的测试代码
void testSList()
{
SList list;
for (int i = 0; i < 5; i++)
list.push_back(i * 10);
list.Travel();
list.Insert(0, 50);
list.Insert(6, 60);
list.Insert(3, 70);
list.Travel();
list.pop_back();
list.pop_back();
list.Travel();
list.Delete(0);
list.Delete(3);
list.Delete(2);
list.Travel();
}
int main()
{
//testList();
//testDList();
//testCList();
testSList();
return 0;
}