雙向循環鏈表可理解爲一個閉環,通常爲了區別和操做方便,頭結點不存內容。如下是整個過程的代碼實現node
#include <stdio.h> typedef int DATATYPE;//定義int的別名,以防止之後結點內容不是int了能夠方便替換 //定義鏈表結點結構體 struct node { DATATYPE data;//數據域 struct node *left;//指向前一個結點,用left其實更便於理解 struct node *right;//指向後一個結點用right也是爲了便於理解,next也不錯 }; typedef struct node Node;//定義別名,方便書寫 Node * createDList();//建立雙向循環鏈表 int insertList1(Node *head, DATATYPE data);//頭插法插入 int insertList2(Node *head, DATATYPE data);//尾插法插入 void printDlist(Node * head);//打印鏈表內容 Node *searchNode(Node *head, DATATYPE find);//查找鏈表中的元素,雙向查找 void sortList1(Node *head, int len);//交換內容排序 基於冒泡 void sortList2(Node *head, int len);//交換指針排序 基於冒泡 void sortList3(Node *head, int len);//基於選擇排序的交換內容排序 int deleteNode(Node *head, DATATYPE data);//刪除指定節點 int lenList(Node *head);//求雙向循環鏈表的長度 void destroyList(Node *head);//求雙向循環鏈表的長度 int main(void) { Node *head = createDList();//建立鏈表 printf("head=%p\n", head); int i = 0; for (i = 7; i >= 0; i--)//爲鏈表賦初始測試值 // insertList1(head, i); insertList2(head, i); printDlist(head); printf("——————\n"); DATATYPE find = 3;//測試查找函數 Node *search=searchNode(head, find); if (search != NULL) printf("search=%d\n", search->data); else printf("no such number\n"); DATATYPE data = 0; deleteNode(head, data);//測試刪除函數 int len = lenList(head);//測試求長度函數 printf("len=%d\n",len); // sortList1(head, len);//測試排序函數 // sortList2(head, len); sortList3(head, len); printDlist(head); destroyList(head);//銷燬全部結點 printf("銷燬後的頭節點:=%p\n",head->right); printf("sizeof(head)=%d\n",sizeof(head)); return 0; } //建立雙向循環鏈表,只須要返回一個頭結點就好 //雙向循環鏈表,就想一個閉環同樣的概念,通常頭結點中不存儲內容 Node * createDList() { Node *head = (Node *)malloc(sizeof(Node)); if (head) { head->left = head; head->right = head; return head; } else return NULL; } //頭插法插入,每次插入在頭結點後緊跟着 int insertList1(Node *head, DATATYPE data) { Node *newNode = (Node *)malloc(sizeof(Node)); if (newNode) { newNode->data = data; newNode->left = head; newNode->right = head->right; head->right = newNode; newNode->right->left = newNode; return 1; } else return -1; } //尾插法插入,每次插入在頭結點以前 int insertList2(Node *head, DATATYPE data) { Node *newNode = (Node *)malloc(sizeof(Node)); if (newNode) { newNode->data = data; head->left->right = newNode; newNode->left = head->left; newNode->right = head; head->left = newNode; return 1; } return -1; } //打印鏈表內容 void printDlist(Node * head) { Node *p = head->right; while (p != head) { printf("%d\n", p->data); p = p->right; } } //查找鏈表中的元素,雙向查找 Node *searchNode(Node *head, DATATYPE find) { Node *left = head;//left表示一個結點的前驅結點,初始值是頭結點 Node *right = head;//right表示一個結點的後繼結點,初始值是頭結點 do { left = left->left;//移動向前一個 right = right->right;//移動向後一個 if (left->data == find)//若是此時結點發現查找內容,就返回結點信息 return left; if (right->data == find)//若是此時結點發現查找內容,就返回結點信息 return right; } while (left != right && left->left!=right);//當兩個結點相遇或者錯過期候終止循環 //若是除了頭結點是偶數個,則相互錯過期候終止 //若是除了頭結點是奇數個,則相遇時候終止查找 return NULL; } //交換內容排序 基於冒泡 void sortList1(Node *head, int len) { int i = 0, j = 0; Node *p, *q; for (i = 0; i < len - 1; i++) { p = head->right; q = p->right; for (j = 0; j < len - 1 - i; j++) { if (p->data<q->data){ p->data ^= q->data; q->data ^= p->data; p->data ^= q->data; } p = p->right; q = q->right; } } } //交換指針排序 基於冒泡 void sortList2(Node *head, int len) { Node *p, *q; int i = 0, j = 0; for (i = 0; i < len - 1; i++) { p = head->right; q = p->right; for (j = 0; j < len - 1-i; j++) { if (p->data < q->data){ q->left = p->left; p->left->right = q; p->right = q->right; q->right->left = p; q->right = p; p->left = q; q = p->right; } else{ p = p->right; q = q->right; } } } } //基於選擇排序的交換內容排序 void sortList3(Node *head, int len) { Node *p, *q, *max, *temp; DATATYPE t; p = head->right; q = p->right; int i = 0, j = 0; for (i = 0; i < len-1 ; i++) { if (p == head) break; max = p; q = p; for (j = i; j < len; j++) { if (q == head) break; if (max->data > q->data) max = q; q = q->right; } if (max != p) { t = max->data; max->data = p->data; p->data = t; } p = p->right; } } //基於選擇排序的交換指針排序,寫了可是一直出問題? //刪除指定節點 int deleteNode(Node *head, DATATYPE data) { Node *search = searchNode(head, data); if (search){ search->left->right = search->right; search->right->left = search->left; free(search); return 1; } return 0; } //求雙向循環鏈表的長度 int lenList(Node *head) { Node *p = head; int len = 0; while (p->right != head){ len++; p = p->right; } return len; } //銷燬全部記錄 void destroyList(Node *head) { Node *p = head->right; while (p != head) { p = p->right; free(p->left); } free(head); }