数据结构四双向链表

来源:互联网 发布:艾宾浩斯记忆软件 编辑:程序博客网 时间:2024/06/06 01:42

 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。而之前的单链表为单向链表,双向链表也就是在单链表的结点中增加一个指向其前驱的pre指针

        如图

        

        

        这里介绍双向链表的常用操作:

               l 创建双向链表

               l 销毁双向链表

               l 清空双向链表

               l 获取表长度

               l 把node插入pos位置

               l 获取pos位置的元素

               l 删除pos位置的元素

               l 删除表中与node相同的元素(删除第一个匹配成功的)

               l 重置游标

               l 返回游标所指向的结点

               l 游标后移

               l 游标前移

 

         代码总分为三个文件:

                     DLinkList.h : 放置功能函数的声明,以及表的声明,表结点的定义 

                     DLinkList.c : 放置功能函数的定义,以及表的定义

                     Main.c    : 主函数,使用功能函数完成各种需求,一般用作测试

        整体结构图为:

 

        

        

              这里详细说下插入操作和删除操作:

 

              插入操作

                        如图

 

                                        

             

              插入元素方法:

                       判断表和插入位置是否合法

                       由表头开始通过next域移动pos次后,当前元素的next域为要插入的位置

                       Current的next域指向node

                       Node的next域指向next

                       判断是否为尾插,如果不是的话next的pre域指向node

                       判断是否为头插,如果是的话node的pre域指向NULL 

                      如果之前表为空表,则游标指向插入的结点

                      表长度加1

  

              删除操作

                        如图

 

                 

              删除元素方法:

                     判断表和插入位置是否合法

                     由表头开始通过next域移动pos次后,当前元素的next指向的元素为要删除的元素

                     把current的next域指向next

                     判断是否为尾插,如果不是的话,next的pre指针指向current

                     如果不是尾插且是头插的话,next的pre指针指向NULL

                     如果删除的结点正好游标也指向它,则游标后移

                     表长度减1

             

             OK! 上代码:

                                     DLinkList.h :

                      

[cpp] view plain copy
  1. #ifndef _DLINKLIST_H_  
  2. #define _DLINKLIST_H_  
  3.   
  4. typedef void DLinkList;  
  5. typedef struct _tag_DLinkListNode DLinkListNode;  
  6.   
  7. struct _tag_DLinkListNode  
  8. {  
  9.     DLinkListNode* next;  
  10.     DLinkListNode* pre;  
  11. };  
  12.   
  13. DLinkList* DLinkList_Create();  
  14.   
  15. void DLinkList_Destroy(DLinkList* list);  
  16.   
  17. void DLinkList_Clear(DLinkList* list);  
  18.   
  19. int DLinkList_Length(DLinkList* list);  
  20.   
  21. int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos);  
  22.   
  23. DLinkListNode* DLinkList_Get(DLinkList* list, int pos);  
  24.   
  25. DLinkListNode* DLinkList_Delete(DLinkList* list, int pos);  
  26.   
  27. DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node);  
  28.   
  29. DLinkListNode* DLinkList_Reset(DLinkList* list);  
  30.   
  31. DLinkListNode* DLinkList_Current(DLinkList* list);  
  32.   
  33. DLinkListNode* DLinkList_Next(DLinkList* list);  
  34.   
  35. DLinkListNode* DLinkList_Pre(DLinkList* list);  
  36.   
  37. #endif  


 

                      DLinkList.c : 

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <malloc.h>  
  3. #include "DLinkList.h"  
  4.   
  5. typedef struct _tag_DLinkList  
  6. {  
  7.     DLinkListNode header;  
  8.     DLinkListNode* slider;  
  9.     int length;  
  10. }TDLinkList;  
  11.   
  12. DLinkList* DLinkList_Create()  
  13. {  
  14.     TDLinkList* sList = (TDLinkList*)malloc(sizeof(TDLinkList));  
  15.       
  16.     if(NULL != sList)  
  17.     {  
  18.         sList->header.next = NULL;  
  19.         sList->header.pre = NULL;  
  20.         sList->slider = NULL;  
  21.         sList->length = 0;  
  22.     }  
  23.       
  24.     return sList;  
  25. }  
  26.   
  27. void DLinkList_Destroy(DLinkList* list)  
  28. {  
  29.     free(list);  
  30. }  
  31.   
  32. void DLinkList_Clear(DLinkList* list)  
  33. {  
  34.     TDLinkList* sList = (TDLinkList*)list;  
  35.       
  36.     if(NULL != sList)  
  37.     {  
  38.         sList->header.next = NULL;  
  39.         sList->header.pre = NULL;  
  40.         sList->slider = NULL;  
  41.         sList->length = 0;  
  42.     }  
  43. }  
  44.   
  45. int DLinkList_Length(DLinkList* list)  
  46. {  
  47.     TDLinkList* sList = (TDLinkList*)list;  
  48.       
  49.     int ret = -1;  
  50.       
  51.     if(NULL != sList)  
  52.     {  
  53.         ret = sList->length;  
  54.     }  
  55.       
  56.     return ret;  
  57. }  
  58.   
  59. int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos)  
  60. {  
  61.     TDLinkList* sList = (TDLinkList*)list;  
  62.       
  63.     int ret = (NULL!=sList)&&(NULL!=node)&&(0<=pos);  
  64.       
  65.     int i = 0;  
  66.       
  67.     if(ret)  
  68.     {  
  69.         DLinkListNode* current = (DLinkListNode*)sList;  
  70.         DLinkListNode* next = NULL;  
  71.           
  72.         for(i=0; (i<pos)&&(NULL!=current->next); i++)  
  73.         {  
  74.             current = current->next;  
  75.         }  
  76.           
  77.         next = current->next;  
  78.         current->next = node;  
  79.         node->next = next;  
  80.           
  81.         if(NULL != next)  
  82.         {  
  83.             next->pre = node;  
  84.         }  
  85.         node->pre = current;  
  86.           
  87.         if(0 == sList->length)  
  88.         {  
  89.             sList->slider = node;  
  90.         }  
  91.           
  92.         if(current == (DLinkListNode*)sList)  
  93.         {  
  94.             node->pre = NULL;  
  95.         }  
  96.           
  97.         sList->length++;  
  98.     }  
  99.       
  100.     return ret;  
  101. }  
  102.   
  103. DLinkListNode* DLinkList_Get(DLinkList* list, int pos)  
  104. {  
  105.     TDLinkList* sList = (TDLinkList*)list;  
  106.       
  107.     DLinkListNode* ret = NULL;  
  108.       
  109.     int i = 0;  
  110.       
  111.     if((NULL!=sList) && (0<=pos) && (0<sList->length))  
  112.     {  
  113.         DLinkListNode* current = (DLinkListNode*)sList;  
  114.           
  115.         for(i=0; i<pos; i++)  
  116.         {  
  117.             current = current->next;   
  118.         }     
  119.           
  120.         ret = current->next;  
  121.     }  
  122.       
  123.     return ret;  
  124. }  
  125.   
  126. DLinkListNode* DLinkList_Delete(DLinkList* list, int pos)  
  127. {  
  128.     TDLinkList* sList = (TDLinkList*)list;  
  129.       
  130.     DLinkListNode* ret = NULL;  
  131.       
  132.     int i = 0;  
  133.       
  134.     if((NULL!=sList) && (0<=pos) && (0<sList->length))  
  135.     {  
  136.         DLinkListNode* current = (DLinkListNode*)sList;  
  137.         DLinkListNode* next = NULL;  
  138.           
  139.         for(i=0; i<pos; i++)  
  140.         {  
  141.             current = current->next;  
  142.         }  
  143.           
  144.         ret = current->next;  
  145.         next = ret->next;  
  146.         current->next = next;  
  147.           
  148.         if(NULL != next)  
  149.         {  
  150.             next->pre = current;  
  151.               
  152.             if(current == (DLinkListNode*)sList)  
  153.             {  
  154.                 next->pre = NULL;  
  155.             }  
  156.         }  
  157.           
  158.         if(ret == sList->slider)  
  159.         {  
  160.             sList->slider = next;  
  161.         }  
  162.           
  163.         sList->length--;  
  164.     }  
  165.       
  166.     return ret;  
  167. }  
  168.   
  169. DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node)  
  170. {  
  171.     TDLinkList* sList = (TDLinkList*)list;  
  172.       
  173.     DLinkListNode* ret = NULL;  
  174.       
  175.     int i = 0;  
  176.       
  177.     if((NULL!=sList) && (NULL!=node))  
  178.     {  
  179.         DLinkListNode* current = (DLinkListNode*)sList;  
  180.           
  181.         for(i=0; i<sList->length; i++)  
  182.         {  
  183.             if(node == current->next)  
  184.             {  
  185.                 ret = current->next;  
  186.                 break;  
  187.             }  
  188.               
  189.             current = current->next;  
  190.         }  
  191.           
  192.         if(NULL != ret)  
  193.         {  
  194.             DLinkList_Delete(sList, i);  
  195.         }  
  196.     }  
  197.       
  198.     return ret;  
  199. }  
  200.   
  201. DLinkListNode* DLinkList_Reset(DLinkList* list)  
  202. {  
  203.     TDLinkList* sList = (TDLinkList*)list;  
  204.       
  205.     DLinkListNode* ret = NULL;  
  206.       
  207.     if(NULL != sList)  
  208.     {  
  209.         sList->slider = sList->header.next;  
  210.         ret = sList->slider;  
  211.     }  
  212.       
  213.     return ret;  
  214. }  
  215.   
  216. DLinkListNode* DLinkList_Current(DLinkList* list)  
  217. {  
  218.     TDLinkList* sList = (TDLinkList*)list;  
  219.       
  220.     DLinkListNode* ret = NULL;  
  221.       
  222.     if(NULL != sList)  
  223.     {  
  224.         ret = sList->slider;  
  225.     }  
  226.       
  227.     return ret;  
  228. }  
  229.   
  230. DLinkListNode* DLinkList_Next(DLinkList* list)  
  231. {  
  232.     TDLinkList* sList = (TDLinkList*)list;  
  233.       
  234.     DLinkListNode* ret = NULL;  
  235.       
  236.     if(NULL != sList)  
  237.     {  
  238.         ret = sList->slider;  
  239.         sList->slider = ret->next;  
  240.     }  
  241.       
  242.     return ret;  
  243. }  
  244.   
  245. DLinkListNode* DLinkList_Pre(DLinkList* list)  
  246. {  
  247.     TDLinkList* sList = (TDLinkList*)list;  
  248.       
  249.     DLinkListNode* ret = NULL;  
  250.       
  251.     if(NULL != sList)  
  252.     {  
  253.         ret = sList->slider;  
  254.         sList->slider = ret->pre;  
  255.     }  
  256.       
  257.     return ret;  
  258. }  


 

                      Main.c :

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "DLinkList.h"  
  4.   
  5. typedef struct _tag_Value  
  6. {  
  7.     DLinkListNode header;  
  8.     int v;  
  9. }Value;  
  10.   
  11. int main(void)  
  12. {  
  13.     DLinkList* list = DLinkList_Create();  
  14.       
  15.     int i = 0;  
  16.       
  17.     Value* pV = NULL;  
  18.       
  19.     Value v1,v2,v3,v4,v5;  
  20.       
  21.     v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;  
  22.       
  23.     DLinkList_Insert(list, (DLinkListNode*)&v1, DLinkList_Length(list));  
  24.     DLinkList_Insert(list, (DLinkListNode*)&v2, DLinkList_Length(list));  
  25.     DLinkList_Insert(list, (DLinkListNode*)&v3, DLinkList_Length(list));  
  26.     DLinkList_Insert(list, (DLinkListNode*)&v4, DLinkList_Length(list));  
  27.     DLinkList_Insert(list, (DLinkListNode*)&v5, DLinkList_Length(list));  
  28.       
  29.     for(i=0; i<DLinkList_Length(list); i++)  
  30.     {  
  31.         pV = (Value*)DLinkList_Get(list, i);  
  32.           
  33.         printf("已发现节点:%d\n", pV->v);  
  34.     }  
  35.     printf("\n");  
  36.       
  37.     DLinkList_Delete(list, DLinkList_Length(list)-1);  
  38.     DLinkList_Delete(list, 0);  
  39.       
  40.     for(i=0; i<DLinkList_Length(list); i++)  
  41.     {  
  42.         pV = (Value*)DLinkList_Next(list);  
  43.           
  44.         printf("已发现节点:%d\n", pV->v);  
  45.     }  
  46.     printf("\n");  
  47.       
  48.     DLinkList_Reset(list);  
  49.     DLinkList_Next(list);  
  50.     pV = (Value*)DLinkList_Current(list);  
  51.     printf("%d\n", pV->v);  
  52.       
  53.     DLinkList_DeleteNode(list, (DLinkListNode*)pV);  
  54.     pV = (Value*)DLinkList_Current(list);  
  55.     printf("%d\n", pV->v);  
  56.       
  57.     DLinkList_Pre(list);  
  58.     pV = (Value*)DLinkList_Current(list);  
  59.     printf("%d\n", pV->v);  
  60.       
  61.     printf("Length: %d\n", DLinkList_Length(list));  
  62.       
  63.     DLinkList_Destroy(list);  
  64.       
  65.     return 0;  
  66. }