第三节 双链表、双循环链表
- 与单链表不同的地方在于双链表多了一个指向它前方节点的指针。正因如此,双链表在使用时对指针的了解要求会更高一点。
- 头插法插入节点时:
- 该链表除了头节点外,不存在其他的节点时,只需要操作两个指针
- 该链表具有多个节点时,需要操作四个指针
- 尾插法插入节点时:
- 首先要遍历链表到最后的一个节点,操作三个指针即可。
- 删除节点时:
- 需要遍历找到想要删除的节点,操作对对应的指针指向,完成删除,不要忘记
free
。
- 需要遍历找到想要删除的节点,操作对对应的指针指向,完成删除,不要忘记
- 头插法插入节点时:
- 定义结构体和初始化:
//定义双链表结构体
typedef struct Node{
int data;
struct Node* pre;
struct Node* next;
}Node;
//初始化双链表
Node* initList(void){
Node* L = (Node*)malloc(sizeof(Node));
L ->data = 0;
L ->pre = NULL;
L ->next = NULL;
return L;
}
- 链表的插入:
//头插法
void headInsert(Node* L , int data){
Node* node = (Node*)malloc(sizeof(Node));
node ->data = data;
if(L ->data == 0){
L ->data++;
L ->next = node;
node ->pre = L;
node ->next = NULL; //或者 node ->next = L -> next;
}
else{
L ->data++;
node ->pre = L;
node ->next = L->next;
L ->next ->pre = node;
L ->next = node;
}
}
//尾插法
void tailInsert(Node* L , int data){
Node* current = L;
Node* node = (Node*)malloc(sizeof(Node));
L ->data++;
node ->data = data;
while(current ->next){
current = current ->next;
}
node ->next = current ->next;
node ->pre = current;
current ->next = node;
}
- 链表的删除:
//删除
void deleat(Node* L , int data){
Node* current = L;
while(current){
if(current->data == data){
current ->pre->next = current ->next;
current ->next->pre = current ->pre;
L ->data--;
printf("Deleat Successfully!\n");
break;
}
current = current ->next;
}
}
- 链表的打印:
//打印双链表
void printList(Node* L){
Node* node = L ->next;
while(node){
printf("%d->",node->data);
node = node ->next;
}
printf("NULL\n");
}
编写主函数,测试结果:
int main()
{
Node* L = initList();
headInsert(L,1);
headInsert(L,1);
headInsert(L,2);
printList(L);
tailInsert(L,2);
printList(L);
deleat(L,1);
printList(L);
}
运行:
2->1->1->NULL
2->1->1->2->NULL
Deleat Successfully!
2->1->2->NULL
双循环链表:
- 与单循环链表相似,因此,这里就不做过多的描述了。
#include "stdio.h"
#include "stdlib.h"
//定义双链表结构体
typedef struct Node{
int data;
struct Node* pre;
struct Node* next;
}Node;
//初始化双循环链表
Node* initList(void){
Node* L = (Node*)malloc(sizeof(Node));
L ->data = 0;
L ->pre = L;
L ->next = L;
return L;
}
//头插法
void headInsert(Node* L , int data){
Node* node = (Node*)malloc(sizeof(Node));
node ->data = data;
if(L ->data == 0){
L ->data++;
node ->pre = L;
node ->next = L -> next;
L ->next = node;
L ->pre = node;
}
else{
L ->data++;
node ->pre = L;
node ->next = L->next;
L ->next ->pre = node;
L ->next = node;
}
}
//尾插法
void tailInsert(Node* L , int data){
Node* current = L;
Node* node = (Node*)malloc(sizeof(Node));
L ->data++;
node ->data = data;
while(current ->next != L){
current = current ->next;
}
node ->next = current ->next;
node ->pre = current;
current ->next = node;
}
//删除
void deleat(Node* L , int data){
Node* current = L ->next;
int temp = L ->data;
while(temp){
temp--;
if(current->data == data){
current ->pre->next = current ->next;
current ->next->pre = current ->pre;
L ->data--;
printf("Deleat Successfully!\n");
break;
}
current = current ->next;
}
}
//打印双链表
void printList(Node* L){
Node* node = L ->next;
int temp = L ->data;
while(temp){
temp--;
printf("%d->",node->data);
node = node ->next;
}
printf("NULL\n");
}
int main()
{
Node* L = initList();
headInsert(L,1);
headInsert(L,1);
headInsert(L,2);
printList(L);
tailInsert(L,2);
printList(L);
deleat(L,1);
printList(L);
}