一口气搞懂「链表」,就靠这20+张图了( 四 )


一口气搞懂「链表」,就靠这20+张图了

文章插图
对于每一次的双向链表的插入操作,首先需要创建一个独立的结点,并通过malloc操作开辟相应的空间;
其次我们选中这个新创建的独立节点,将其的pre指针指向所需插入位置的前一个结点;
同时,其所需插入的前一个结点的next指针修改指向为该新的结点,该新的结点的next指针将会指向一个原本的下一个结点,而修改下一个结点的pre指针为指向新结点自身,这样的一个操作我们称之为双向链表的插入操作 。
其代码可以表示为:
  //插入数据
line * insertLine(line * head,int data,int add){
//三个参数分别为:进行此操作的双链表,插入的数据,插入的位置
//新建数据域为data的结点
line * temp=(line*)malloc(sizeof(line));
temp->data=https://www.isolves.com/it/cxkf/bk/2020-08-31/data;
temp->pre=;
temp->next=;
//插入到链表头,要特殊考虑
if (add==1) {
temp->next=head;
head->pre=temp;
head=temp;
}else{
line * body=head;
//找到要插入位置的前一个结点
for (int i=1; i<add-1; i++) {
body=body->next;
}
//判断条件为真,说明插入位置为链表尾
if (body->next==) {
body->next=temp;
temp->pre=body;
}else{
body->next->pre=temp;
temp->next=body->next;
body->next=temp;
temp->pre=body;
}
}
return head;
}
 
双向链表的删除操作如图:
一口气搞懂「链表」,就靠这20+张图了

文章插图
删除操作的过程是:选择需要删除的结点->选中这个结点的前一个结点->将前一个结点的next指针指向自己的下一个结点->选中该节点的下一个结点->将下一个结点的pre指针修改指向为自己的上一个结点 。
在进行遍历的时候直接将这一个结点给跳过了,之后,我们释放删除结点,归还空间给内存,这样的操作我们称之为双链表的删除操作 。
其代码可以表示为:
  //删除元素
line * deleteLine(line * head,int data){
//输入的参数分别为进行此操作的双链表,需要删除的数据
line * list=head;
//遍历链表
while (list) {
//判断是否与此元素相等
//删除该点方法为将该结点前一结点的next指向该节点后一结点
//同时将该结点的后一结点的pre指向该节点的前一结点
if (list->data=https://www.isolves.com/it/cxkf/bk/2020-08-31/=data) {
list->pre->next=list->next;
list->next->pre=list->pre;
free(list);
printf("--删除成功--n");
return head;
}
list=list->next;
}
printf("Error:没有找到该元素,没有产生删除n");
return head;
}
 
双向链表的遍历双向链表的遍历利用next指针逐步向后进行索引即可 。
注意,在判断这里,我们既可以用while(list)的操作直接判断是否链表为空,也可以使用while(list->next)的操作判断该链表是否为空,其下一节点为空和本结点是否为空的判断条件是一样的效果 。
其简单的代码可以表示为:
  //遍历双链表,同时打印元素数据
void printLine(line *head){
line *list = head;
int pos=1;
while(list){
printf("第%d个数据是:%dn",pos++,list->data);
list=list->next;
}
}
  
循环链表 
循环链表概念对于单链表以及双向链表,就像一个小巷,无论怎么走最终都能从一端走到另一端,顾名思义,循环链表则像一个有传送门的小巷,当你以为你走到结尾的时候,其实这就是开头 。
循环链表和非循环链表其实创建的过程唯一不同的是,非循环链表的尾结点指向空,而循环链表的尾指针指向的是链表的开头 。
通过将单链表的尾结点指向头结点的链表称之为循环单链表(Circular linkedlist)
一个完整的循环单链表如图:
一口气搞懂「链表」,就靠这20+张图了

文章插图
 
循环链表结点设计(以单循环链表为例)对于循环单链表的结点,可以完全参照于单链表的结点设计,如图:
一口气搞懂「链表」,就靠这20+张图了

文章插图
单向循环链表结点
data表示数据;
next表示指针,它总是指向自身的下一个结点,对于只有一个结点的存在,这个next指针则永远指向自身,对于一个链表的尾部结点,next永远指向开头 。


推荐阅读