Doubly Linked List&DLL(双向链表)
双向链表
优点
- 可以从两个方向遍历链表(从前到后,从后到前);
- 删除节点方面效率很高(不像单链表和循环链表需要遍历链表);
- 可以插入元素在给定节点之前(单链表和循环链表只能插在给定节点后面,除了插在头结点之前);
缺点
- 一个双向链表节点要存储两个指针,一个指向下一个节点next,一个指向上一个节点previous,耗费空间资源比较大相较于单链表和循环链表。(这个有XOR链表解决这个问题)
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 struct node 5 { 6 int data; 7 struct node * pre; 8 struct node * next; 9 }; 10 11 void push(struct node ** head_ref, int new_data) 12 { 13 struct node * new_node = (struct node *)malloc(sizeof(struct node)); 14 new_node->data = new_data; 15 new_node->next = (*head_ref); 16 new_node->pre = NULL; 17 //如果链表不为空的话,将上一个头结点的pre指向新的头结点 18 if(NULL != (*head_ref)) 19 { 20 (*head_ref)->pre = new_node; 21 } 22 23 (*head_ref) = new_node; 24 } 25 void insertAfter(struct node * pre_node, int new_data) 26 { 27 if(NULL == pre_node) 28 { 29 printf("\nERROR"); 30 return ; 31 } 32 struct node * new_node = (struct node *)malloc(sizeof(struct node)); 33 34 new_node->data = new_data; 35 36 new_node->next = pre_node->next; 37 pre_node->next = new_node; 38 39 new_node->pre = pre_node; 40 //如果pre_node不是尾节点的话 41 if(NULL != new_node->next) 42 { 43 new_node->next->pre = new_node; 44 } 45 } 46 void insertBefore(struct node * next_node, int new_data) 47 { 48 if(NULL == next_node) 49 { 50 printf("\nERROR"); 51 return ; 52 } 53 struct node * new_node = (struct node *)malloc(sizeof(struct node)); 54 55 new_node->data = new_data; 56 new_node->pre = next_node->pre; 57 next_node->pre = new_node; 58 new_node->next = next_node; 59 //若果next_node不是头结点 60 if(NULL != new_node->pre) 61 { 62 new_node->pre->next = new_node; 63 } 64 } 65 void append(struct node ** head_ref, int new_data) 66 { 67 struct node * new_node = (struct node *)malloc(sizeof(struct node)); 68 struct node * last_node = (*head_ref); 69 new_node->data = new_data; 70 new_node->next = NULL; 71 72 if(NULL == (*head_ref)) 73 { 74 new_node->pre = NULL; 75 (*head_ref) = new_node; 76 return; 77 } 78 while(NULL != last_node) 79 { 80 last_node = last_node->next; 81 } 82 last_node->next = new_node; 83 new_node->pre = last_node; 84 } 85 void deleteElement(struct node ** head_ref, struct node * del) 86 { 87 if(NULL == head_ref && NULL == del) 88 { 89 printf("\nERROR"); 90 return ; 91 } 92 //若删除节点为头结点的next节点 93 if((*head_ref)->next == del) 94 { 95 (*head_ref)->next = del->next; 96 del->next->pre = (*head_ref); 97 } 98 //删除节点不是尾节点的时候 99 if(NULL != del->next) 100 { 101 del->next->pre = del->pre; 102 } 103 //删除节点不是头结点的时候 104 if(NULL != del->pre) 105 { 106 del->pre->next = del->next; 107 } 108 109 free(del); 110 } 111 void printList(struct node * node) 112 { 113 if(NULL == node) 114 { 115 printf("\nERROR"); 116 return ; 117 } 118 119 struct node * last = NULL; 120 printf("Traversal the list forward direction\n"); 121 while(NULL != node) 122 { 123 printf("%d ", node->data); 124 last = node; 125 node = node->next; 126 } 127 printf("\nTraversal the list reverse direction\n"); 128 while(NULL != last) 129 { 130 printf("%d ", last->data); 131 last = last->pre; 132 } 133 } 134 int main(void) 135 { 136 struct node * head = NULL; 137 138 push(&head, 1); 139 push(&head, 4); 140 push(&head, 5); 141 push(&head, 2); 142 143 deleteElement(&head, head->next->next); 144 printList(head); 145 146 return 0; 147 }
感受颇多