双向链表介绍
双向链表的结构如下:
1 2 3 4 5
| struct Node{ int data; struct Node* prev; struct Node* next; };
|
可以看到双向链表的节点是由两个结构体指针及相关数据构成的,因此可以更方便地对链表中的节点进行访问和数据的修改。
双向链表的实现
进行几个基本操作:头部插入(InsertAtHead)、尾部插入(InsertAtTail)、打印(Print)、反向打印(ReversePrint)。
头部插入(InsertAtHead)
插入时要先在堆区开辟一块动态内存,为了避免代码重复,我们设计一个函数GetNewNode(int x),可以在堆区新建一个节点,存储数据x,同时返回堆区内存的地址。
1 2 3 4 5 6 7
| struct Node* GetNewNode(int x){ struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = x; newNode->next = NULL; newNode->prev = NULL; return newNode; }
|
再进行头部插入
1 2 3 4 5 6 7 8 9 10
| void InsertAtHead(int x){ struct Node* newNode = GetNewNode(x); if(head == NULL){ head = newNode; return; } head->prev = newNode; newNode->next = head; head = newNode; }
|
尾部插入(InsertAtTail)
只需要先遍历到最后一个节点,再进行插入操作即可。
1 2 3 4 5 6 7 8 9 10 11 12 13
| void InsertAtTail(int x){ struct Node* newNode = GetNewNode(x); if(head == NULL){ head = newNode; return; } struct Node* temp = head; while(temp->next != NULL){ temp = temp->next; } temp->next = newNode; newNode->prev = temp; }
|
打印(Print)
1 2 3 4 5 6 7 8 9
| void Print(){ struct Node* temp = head; printf("Forward: "); while(temp != NULL){ printf("%d ",temp->data); temp = temp->next; } printf("\n"); }
|
反向打印(ReversePrint)
同样需要先遍历到最后一个节点。
1 2 3 4 5 6 7 8 9 10 11 12
| void ReversePrint(){ struct Node* temp = head; while(temp->next != NULL){ temp = temp->next; } printf("Reverse: "); while(temp != NULL){ printf("%d ",temp->data); temp = temp->prev; } printf("\n"); }
|
完整实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include<stdio.h> #include<stdlib.h> struct Node{ int data; struct Node* prev; struct Node* next; }; struct Node* head = NULL; struct Node* GetNewNode(int x){ struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = x; newNode->next = NULL; newNode->prev = NULL; return newNode; } void InsertAtHead(int x){ struct Node* newNode = GetNewNode(x); if(head == NULL){ head = newNode; return; } head->prev = newNode; newNode->next = head; head = newNode; } void InsertAtTail(int x){ struct Node* newNode = GetNewNode(x); if(head == NULL){ head = newNode; return; } struct Node* temp = head; while(temp->next != NULL){ temp = temp->next; } temp->next = newNode; newNode->prev = temp; } void Print(){ struct Node* temp = head; printf("Forward: "); while(temp != NULL){ printf("%d ",temp->data); temp = temp->next; } printf("\n"); } void ReversePrint(){ struct Node* temp = head; while(temp->next != NULL){ temp = temp->next; } printf("Reverse: "); while(temp != NULL){ printf("%d ",temp->data); temp = temp->prev; } printf("\n"); } int main(){ InsertAtTail(1);Print(); InsertAtHead(3);Print(); InsertAtHead(2);Print(); InsertAtHead(4);Print(); InsertAtTail(5);Print(); ReversePrint(); return 0; }
|
输出结果:
1 2 3 4 5 6
| Forward: 1 Forward: 3 1 Forward: 2 3 1 Forward: 4 2 3 1 Forward: 4 2 3 1 5 Reverse: 5 1 3 2 4
|