首先,我们需要知道什么是链表
https://baike.baidu.com/item/%E9%93%BE%E8%A1%A8/9794473 (可以从这里了解)
-
链表是一种物理存储单元上非连续、非顺序的存储结构
-
链表分为三类:单向链表、双向链表、循环链表
单向链表
链表中最基本的数据称为节点(node),每个节点包含了数据块和指向下一个节点的指针,链表有一个头指针变量,图中以head表示。head指向第一个元素,第一个元素又指向第二个元素……直到最后一个元素,该元素不再指向其他元素,它称为表尾,它的地址部分为空,链表结束。
-
变量声明:
const int maxn=1010; struct node{ //point即指针,data就是需要维护的数据 int point,data; }a[maxn]; int head,cnt; //head即头指针,cnt即内存池计数器
-
建立:
head=++cnt; //把head设为没有实际意义的指针 a[head].data=0;
-
插入(插入数据now到第k个元素之后)
add(++k,now); //进入,因为计算时考虑了head,所以进入时++k void add(int k,int now) { for(int i=head;i;i=a[i].point) //从头指针开始遍历链表 if(!(--k)) //到达插入位置 { a[++cnt].point=a[i].point; //将新插入节点的指针指向插入位置的后继 a[i].point=cnt; //将前驱节点的指针指向新插入节点 a[cnt].data=now; break; } }
-
删除(删除第k个元素):
del(++k); //进入 void del(int k) { for(int i=head;i;i=a[i].point) if((--k)==1) //找到前驱 { a[i].point=a[a[i].point].point; //将前驱的指针指向后继 break; } }
-
遍历链表:
for(int i=a[head].point;i;i=a[i].point)
cout<<a[i].data<<endl;
双向链表
有两个方向的链表。在双向链表中每一个节点不仅存储指向下一个节点的指针,还存储指向前一个节点的指针。
它的优点是访问、插入、删除更方便。但“是以空间换时间。
1. 变量声明:
struct node{
int pre,nxt,data; //前驱和后继
}a[maxn];
int head,cnt;
2.插入:
void add(int k,int now)
{
for(int i=head;i;i=a[i].nxt)
if(!(--k))
{
a[++cnt].nxt=a[i].nxt; //这两个和单链表一样
a[i].nxt=cnt;
a[a[cnt].nxt].pre=cnt; //将后继的前驱更新为新插入节点
a[cnt].pre=i; //将新插入节点的前驱设为其前驱
a[cnt].data=now;
break;
}
}
3. 删除:
void del(int k)
{
for(int i=head;i;i=a[i].nxt)
if(!(--k))
{
a[a[i].pre].nxt=a[i].nxt;
a[a[i].nxt].pre=a[i].pre;
break;
}
}
循环链表
- 单向循环列表(最后一个节点的指针指向头结点)
- 双向循环链表(最后一个节点的指针指向头结点,且头结点的前驱指向最后一个结点)