1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef struct _dnode 5 { 6 int data; 7 struct _dnode *pre; 8 struct _dnode *next; 9 }Dnode;
1 //创建空链表 //让头结点指向自己,方便以后的操作。 2 int createDlist(Dnode** head) 3 { 4 *head = (Dnode*)malloc(sizeof(Dnode)); 5 if(head == NULL) 6 return -1; 7 (*head)->next = *head; 8 (*head)->pre = *head; 9 return 0; 10 }
1 //插入新节点,头插 2 //创建链表时让头结点指向自己目的是 : 3 //功能上不只为一层。为了让多层同样式代码通用化。比如方便实现插入的功能代码。循环要写成通用形式比较难。所以在创建链表时让头节点指向自己,这样可以让空链表状态的插入的功能代码与有节点链表状态的插入的 功能代码一样。 4 void insertDlist(Dnode *head,int data) 5 { 6 7 Dnode *newNode = (Dnode*)malloc(sizeof(Dnode)); 8 newNode->data = data; 9 10 /*插入三步曲,*/ 11 //先处理新节点指向 ,连上左右两边的节点 12 newNode->next = head->next; 13 newNode->pre = head; 14 15 head->next = newNode;//再处理左节点指向,连上新节点 16 newNode->next->pre = newNode;//再处理右节点,连上新节点 17 }
1 //求链表长度 2 int getLenDlist(Dnode* head) 3 { 4 Dnode* cur = head->next; 5 int len = 0; 6 while(cur != head) 7 { 8 len++; 9 cur = cur->next; 10 } 11 return len; 12 }
1 //查找 2 //单向查找 3 Dnode* searchDlist(Dnode* head,int find) 4 { 5 Dnode* cur = head->next; 6 while(cur != head) 7 { 8 if(cur->data == find) 9 return cur; 10 } 11 return NULL; 12 } 13 14 15 //双向查找 16 /*分别从两头往中找,结束时可能会遇见两种情况 17 情况1 碰头了之后再判断一次,如果仍没找到,停止 。找到直接返回 18 情况2 交错之后,如果仍没找到,停止。 19 20 21 22 实现循环中的代码的通用性,就这三条路 23 实现方式1 让情况1为主包含情况2 无法实现 24 实现方式2 让情况2为主包含情况1 可以实现 逻辑是 擦肩而过之前一定会相遇 25 实现方式3 同时包含情况1情况2 ,两种情况平行 使用while(1)把这个也实现下 26 (把这个实现循环通用化的思想好好总结一下,感觉特别重要,常常会遇见写循环时需要实现有多种情况通用化的合体代码) 27 */ 28 29 //实现方式2 30 Dnode* searchDlist2(Dnode* head,int find) 31 { 32 Dnode* clock = head->next; 33 Dnode* unclock = head->pre; 34 35 while(clock != unclock->next)//也可以while(unclock != clock->pre) //以情况2为主 36 { 37 if(clock->data == find) 38 return clock; 39 if(unclock->data == find) 40 return unclock; 41 42 if(clock == unclock)//以情况1为次 43 break; 44 45 clock = clock->next; 46 unclock = unclock->pre; 47 } 48 return NULL; 49 } 50 //实现方式3 //感觉不对劲,虽然测对了 51 Dnode* searchDlist3(Dnode* head,int find) 52 { 53 Dnode* clock = head->next; 54 Dnode* unclock = head->pre; 55 56 while(1) 57 { 58 if(clock->data == find) 59 return clock; 60 if(unclock->data == find) 61 return unclock; 62 63 if(clock == unclock || clock == unclock->next) 64 break; 65 66 67 clock = clock->next; 68 unclock = unclock->pre; 69 } 70 return NULL; 71 72 }
1 //删除 2 //不用像单链表那样找前驱了,双链表可以直接访问到前驱。 3 void deleteDlistNode(Dnode *deleteNode) 4 { 5 deleteNode->pre->next = deleteNode->next; 6 deleteNode->next->pre = deleteNode->pre; 7 free(deleteNode); 8 9 }
1 //销毁 //包括头结点一起销毁,另需将头指针指向NULL 2 //方式1 3 void destroyDlist1(Dnode** head) 4 { 5 Dnode* cur = (*head)->next; 6 while(cur != *head) 7 { 8 Dnode* temp = cur; 9 cur = cur->next; 10 free(temp); 11 } 12 free(*head); 13 *head = NULL; 14 } 15 //方式2,先把双向链表废成单向链表,再一一删除 16 void destroyDlist2(Dnode** head) 17 { 18 (*head)->pre->next = NULL; 19 while(*head)//遍历完后*head==NULL 20 { 21 Dnode* temp = *head; 22 *head = (*head)->next; 23 free(temp); 24 } 25 }
1 //排序 2 3 4 //对数据域进行交换 5 //用冒泡排序实现 6 void bubbleSortDlistData(Dnode* head) 7 { 8 int len = getLenDlist(head); 9 Dnode* pcur = head; 10 Dnode* pnext; 11 int i,j; 12 for(i = 0; i < len-1;i++) 13 { 14 pcur = head->next; 15 pnext = pcur->next; 16 for(j = 0;j<len-1-i;j++) 17 { 18 19 if(pcur->data > pnext->data) 20 { 21 pcur->data ^= pnext->data; 22 pnext->data ^= pcur->data; 23 pcur->data ^= pnext->data; 24 } 25 26 pcur = pcur->next; 27 pnext = pcur->next; 28 } 29 } 30 } 31 32 //用选择排序实现 33 void selectSortDlistData(Dnode* head)//升序 34 { 35 int len = getLenDlist(head); 36 Dnode* pcur; 37 Dnode* pnext; 38 39 for(pcur = head->next; pcur->next != head ;pcur = pcur->next) 40 { 41 for(pnext = pcur->next;pnext != head;pnext = pnext->next) 42 { 43 if(pcur->data > pnext->data) 44 { 45 pcur->data ^= pnext->data; 46 pnext->data ^= pcur->data; 47 pcur->data ^= pnext->data; 48 } 49 } 50 } 51 52 53 } 54 55 56 //对指针域进行交换 57 //不再像单链表那样专门记录前驱节点地址,因为有pre成员 58 59 60 //使用冒泡排序实现 61 void bubbleSortDlistPointer(Dnode* head)//升序 62 { 63 int len = getLenDlist(head); 64 Dnode* pcur; 65 Dnode* pnext; 66 67 int i,j; 68 for(i = 0;i<len-1;i++) 69 { 70 pcur = head->next; 71 pnext = pcur->next; 72 for(j=0;j<len-1-i;j++) 73 { 74 if(pcur->data > pnext->data) 75 { 76 pcur->pre->next = pnext; 77 pnext->pre = pcur->pre; 78 79 pcur->next = pnext->next; 80 pnext->next->pre = pnext; 81 82 pnext->next = pcur; 83 pcur->pre = pnext; 84 85 86 87 pcur = pcur->pre; 88 } 89 pcur = pcur->next; 90 pnext = pcur->next; 91 } 92 } 93 } 94 95 96 //使用选择排序实现 97 //待补
1 //遍历 2 3 //遍历节点,向前 4 void traverseDlistNext(Dnode* head) 5 { 6 Dnode* phead = head->next; 7 while(phead != head) 8 { 9 printf("%d ",phead->data); 10 phead = phead->next; 11 } 12 putchar(10); 13 } 14 15 //遍历节点,向后 16 void traverseDlistPre(Dnode* head) 17 { 18 Dnode* phead = head->pre; 19 while(phead != head) 20 { 21 printf("%d ",phead->data); 22 phead = phead->pre; 23 } 24 putchar(10); 25 }