(C/C++學習)18.C語言雙向連結串列
阿新 • • 發佈:2018-11-22
說明:陣列提供了連續記憶體空間的訪問和使用,而連結串列是對記憶體零碎空間的有效組織和使用。連結串列又分為單向連結串列和雙向連結串列,單向連結串列僅提供了連結串列的單方向訪問,相比之下,雙向連結串列則顯得十分方便。
一.單向連結串列的節點
如下程式碼所示,雙向連結串列的節點包含兩個指向關係和一個數據空間,兩個指向分別連線該節點的上一個和下一個節點,資料型別可以是一個結構體型別,也可以是其他型別。
1 typedef struct node 2 { 3 int data; 4 struct node *pre; 5 struct node *next; 6}Node;
二.雙向連結串列的建立
頭插法和尾插法只看程式碼比較難以與理解,建議畫出插入節點時的連結串列變化圖則會非常容易理解,另外,個人認為頭插法較優,因為其插入邏輯一步到位,不像尾插法還需在後面完成雙向連結串列的環狀連線。
1.頭插法
1 Node * creatList() 2 { 3 Node * head = (Node*)malloc(sizeof(Node)); 4 Node * cur = NULL; 5 head->next = head; 6 head->pre = head; 7 int data; 8scanf("%d",&data); 9 while(data) 10 { 11 cur = (Node*)malloc(sizeof(Node)); 12 cur->data = data; 13 cur->next = head->next; 14 cur->pre = head; 15 head->next = cur; 16 cur->next->pre = cur; 17 scanf("%d",&data); 18} 19 return head; 20 }
2.尾插法
1 Node * creatList() 2 { 3 Node * head = (Node*)malloc(sizeof(Node)); 4 Node * phead = head; 5 Node * cur = NULL; 6 phead->next = NULL; 7 phead->pre = NULL; 8 int data; 9 scanf("%d",&data); 10 while(data) 11 { 12 cur = (Node*)malloc(sizeof(Node)); 13 cur->data = data; 14 phead->next = cur; 15 cur->pre = phead; 16 phead = cur; 17 scanf("%d",&data); 18 } 19 //完成迴環 20 cur->next = head; 21 head->pre = cur; 22 return head; 23 }
三.雙向連結串列的元素插入(頭插法)
插入方法:先讓插入的節點有所指向,再考慮指向它的指標,具體插入如下:
1 void insertList(Node * head) 2 { 3 printf("intsert new node:"); 4 int data; 5 scanf("%d",&data); 6 Node * cur; 7 cur = (Node*)malloc(sizeof(Node)); 8 cur->data = data; 9 cur->next = head->next; 10 cur->pre = head; 11 head->next = cur; 12 cur->next->pre = cur; 13 }
四.雙向連結串列的查詢
既然是雙向連結串列,其查詢方式也應該是是雙向查詢,比起單向連結串列的單向查詢,雙向查詢同時從兩個方向進行查詢,加快了查詢的速度。
1 Node * searchList(Node * head,int find) 2 { 3 Node * pClock = head->next; 4 Node * pAntiClock = head->pre; 5 while (pAntiClock != pClock->pre) 6 { 7 if(pClock->data == find) 8 return pClock; 9 if(pAntiClock->data == find) 10 return pAntiClock; 11 if(pClock == pAntiClock) 12 return NULL; 13 pClock = pClock->next; 14 pAntiClock = pAntiClock->pre; 15 } 16 return NULL; 17 }
五.刪除某個節點
1 void deleteList(Node * pfind) 2 { 3 if(pfind == NULL) 4 return; 5 else 6 { 7 pfind->pre->next = pfind->next; 8 pfind->next->pre = pfind->pre; 9 free(pfind); 10 } 11 }
六.連結串列排序(按值排序)
1 void sortList(Node * head,int n) 2 { 3 Node * p,*q; 4 for(int i=0; i<n-1; i++) 5 { 6 p = head->next; 7 q = p->next; 8 for(int j=0; j<n-1-i; j++) 9 { 10 if(p->data > q->data) 11 { 12 p->data = p->data ^ q->data; 13 q->data = p->data ^ q->data; 14 p->data = p->data ^ q->data; 15 } 16 p = p->next; 17 q = q->next; 18 } 19 } 20 }
七.連結串列的銷燬
1 void destroyList(Node * head) 2 { 3 head->pre->next = NULL; 4 Node * pre = head; 5 while(head != NULL) 6 { 7 head = head->next; 8 free(pre); 9 pre = head; 10 } 11 }
說明:連結串列的操作還有如求長度、列印以及交換指標排序等,由於相對較為簡單,此處就不再例舉。重要提醒:連結串列的某些操作較難理解,最好畫圖加以輔助理解。