数据结构之双向循环链表

来源:互联网 发布:2015年江苏省旅游数据 编辑:程序博客网 时间:2024/05/16 07:12

            双向循环链表,也就是在双向链表的基础上加上循环链表的特性,使其首尾相连。最后的next指针指向首元素,而首元素的pre指针指向尾元素。

                如图

              

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

  • l 创建双向链表
  • l 销毁双向链表
  • l 清空双向链表
  • l 获取表长度
  • l 把node插入pos位置
  • l 获取pos位置的元素
  • l 删除pos位置的元素
  • l 删除表中与node相同的元素(删除第一个匹配成功的)
  • l 重置游标
  • l 返回游标所指向的结点
  • l 游标后移
  • l 游标前移

代码总分为三个文件:

 

    • DLinkCircleList.h : 放置功能函数的声明,以及表的声明,表结点的定义 
    • DLinkCircleList.c : 放置功能函数的定义,以及表的定义
    • Main.c            : 主函数,使用功能函数完成各种需求,一般用作测试

整体结构图为:

 

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

 

   插入操作:

           如图

 

                        

           插入元素方法:

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

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

 判断是否为空表

 是空表的话进行空表插入

 不是空表的话判断是否为头插,如果是头插的话进行头插

 不是空表且不是头插则为正常情况和尾插,则进行正常情况的插入

 表长度加1

  

  删除操作:

           如图

         

                 

           删除元素方法:

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

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

 判断长度是否为1,如果为1的话则直接清空表

 判断是否为头删

 是头删的话,进行头删

 不是头删的话则为尾删和正常情况,则按正常情况删除

 表长度减1

 如果游标指向的是要删除的元素,则后移,指向next

 

 

OK! 上代码:

DLinkCircleList.h :

[cpp] view plain copy


  1. #ifndef _DLINKCIRCLELIST_H_  
  2. #define _DLINKCIRCLELIST_H_  
  3.   
  4. typedef void DLinkCircleList;  
  5. typedef struct _tag_DLinkCircleListNode DLinkCircleListNode;  
  6.   
  7. struct _tag_DLinkCircleListNode  
  8. {  
  9.     DLinkCircleListNode* next;  
  10.     DLinkCircleListNode* pre;  
  11. };  
  12.   
  13. DLinkCircleList* DLinkCircleList_Create();  
  14.   
  15. void DLinkCircleList_Dstroy(DLinkCircleList* list);  
  16.   
  17. void DLinkCircleList_Clear(DLinkCircleList* list);  
  18.   
  19. int DLinkCircleList_Length(DLinkCircleList* list);  
  20.   
  21. int DLinkCircleList_Insert(DLinkCircleList* list, DLinkCircleListNode* node, int pos);  
  22.   
  23. DLinkCircleListNode* DLinkCircleList_Get(DLinkCircleList* list, int pos);  
  24.   
  25. DLinkCircleListNode* DLinkCircleList_Delete(DLinkCircleList* list, int pos);  
  26.   
  27. DLinkCircleListNode* DLinkCircleList_DeleteNode(DLinkCircleList* list, DLinkCircleListNode* node);  
  28.   
  29. DLinkCircleListNode* DLinkCircleList_Reset(DLinkCircleList* list);  
  30.   
  31. DLinkCircleListNode* DLinkCircleList_Current(DLinkCircleList* list);  
  32.   
  33. DLinkCircleListNode* DLinkCircleList_Next(DLinkCircleList* list);  
  34.   
  35. DLinkCircleListNode* DLinkCircleList_Pre(DLinkCircleList* list);  
  36.   
  37. #endif  


 

DLinkCircleList.c :

 

[cpp] view plain copy


  1. #include <stdio.h>  
  2. #include <malloc.h>  
  3. #include “DLinkCircleList.h”  
  4.   
  5. typedef struct _tag_DLinkCircleList  
  6. {  
  7.     DLinkCircleListNode header;  
  8.     DLinkCircleListNode* slider;  
  9.     int length;  
  10. }TDLinkCircleList;  
  11.   
  12. DLinkCircleList* DLinkCircleList_Create()  
  13. {  
  14.     TDLinkCircleList* sList = (TDLinkCircleList*)malloc(sizeof(TDLinkCircleList));  
  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 DLinkCircleList_Destroy(DLinkCircleList* list)  
  28. {  
  29.     free(list);  
  30. }  
  31.   
  32. void DLinkCircleList_Clear(DLinkCircleList* list)  
  33. {  
  34.     TDLinkCircleList* sList = (TDLinkCircleList*)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 DLinkCircleList_Length(DLinkCircleList* list)  
  46. {  
  47.     TDLinkCircleList* sList = (TDLinkCircleList*)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 DLinkCircleList_Insert(DLinkCircleList* list, DLinkCircleListNode* node, int pos)  
  60. {  
  61.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  62.       
  63.     int ret = (NULL!=sList)&&(NULL!=node)&&(0<=pos);  
  64.       
  65.     int i = 0;  
  66.       
  67.     if(ret)  
  68.     {  
  69.         DLinkCircleListNode* current = (DLinkCircleListNode*)sList;  
  70.         DLinkCircleListNode* 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.           
  80.         if(0 == sList->length)  
  81.         {  
  82.             node->next = node;  
  83.             node->pre = node;  
  84.             sList->slider = node;  
  85.         }  
  86.         else  
  87.         {  
  88.             if(current == (DLinkCircleListNode*)sList)  
  89.             {  
  90.                 node->next = next;  
  91.                 (next->pre)->next = node;  
  92.                 node->pre = next->pre;  
  93.                 next->pre = node;  
  94.             }  
  95.             else  
  96.             {  
  97.                 node->next = next;  
  98.                 next->pre = node;  
  99.                 node->pre = current;  
  100.             }  
  101.         }  
  102.           
  103.         sList->length++;  
  104.     }  
  105.       
  106.     return ret;  
  107. }  
  108.   
  109. DLinkCircleListNode* DLinkCircleList_Get(DLinkCircleList* list, int pos)  
  110. {  
  111.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  112.       
  113.     DLinkCircleListNode* ret = NULL;  
  114.       
  115.     int i = 0;  
  116.       
  117.     if((NULL!=sList)&&(0<=pos)&&(0<sList->length))  
  118.     {  
  119.         DLinkCircleListNode* current = (DLinkCircleListNode*)sList;  
  120.           
  121.         for(i=0; (i<pos)&&(NULL!=current->next); i++)  
  122.         {  
  123.             current = current->next;  
  124.         }  
  125.           
  126.         ret = current->next;  
  127.     }  
  128.       
  129.     return ret;  
  130. }  
  131.   
  132. DLinkCircleListNode* DLinkCircleList_Delete(DLinkCircleList* list, int pos)  
  133. {  
  134.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  135.       
  136.     DLinkCircleListNode* ret = NULL;  
  137.       
  138.     int i = 0;  
  139.       
  140.     if((NULL!=sList)&&(0<=pos)&&(0<sList->length))  
  141.     {  
  142.         DLinkCircleListNode* current = (DLinkCircleListNode*)sList;  
  143.         DLinkCircleListNode* next = NULL;  
  144.           
  145.         for(i=0; (i<pos)&&(NULL!=current->next); i++)  
  146.         {  
  147.             current = current->next;  
  148.         }  
  149.           
  150.         if(1 == sList->length)  
  151.         {  
  152.             ret = sList->header.next;  
  153.             DLinkCircleList_Clear(sList);  
  154.               
  155.             return ret;  
  156.         }  
  157.           
  158.         ret = current->next;  
  159.         next = ret->next;  
  160.         current->next = next;  
  161.           
  162.         if(current == (DLinkCircleListNode*)sList)  
  163.         {  
  164.             next->pre = ret->pre;  
  165.             (ret->pre)->next = next;  
  166.         }  
  167.         else  
  168.         {  
  169.             next->pre = current;  
  170.         }  
  171.           
  172.         sList->length–;  
  173.           
  174.         if(ret == sList->slider)  
  175.         {  
  176.             sList->slider = next;  
  177.         }  
  178.     }  
  179.       
  180.     return ret;  
  181. }  
  182.   
  183. DLinkCircleListNode* DLinkCircleList_DeleteNode(DLinkCircleList* list, DLinkCircleListNode* node)  
  184. {  
  185.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  186.       
  187.     DLinkCircleListNode* ret = NULL;  
  188.       
  189.     int i = 0;  
  190.       
  191.     if((NULL!=sList)&&(NULL!=node))  
  192.     {  
  193.         DLinkCircleListNode* current = (DLinkCircleListNode*)sList;  
  194.           
  195.         for(i=0; i<sList->length; i++)  
  196.         {  
  197.             if(node == current->next)  
  198.             {  
  199.                 ret = current->next;  
  200.                 break;  
  201.             }  
  202.               
  203.             current = current->next;  
  204.         }  
  205.           
  206.         if(NULL != ret)  
  207.         {  
  208.             DLinkCircleList_Delete(sList, i);  
  209.         }  
  210.     }  
  211.       
  212.     return ret;  
  213. }  
  214.   
  215. DLinkCircleListNode* DLinkCircleList_Reset(DLinkCircleList* list)  
  216. {  
  217.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  218.       
  219.     DLinkCircleListNode* ret = NULL;  
  220.       
  221.     if(NULL!=sList)  
  222.     {  
  223.         sList->slider = sList->header.next;  
  224.         ret = sList->slider;  
  225.     }  
  226.       
  227.     return ret;  
  228. }  
  229.   
  230. DLinkCircleListNode* DLinkCircleList_Current(DLinkCircleList* list)  
  231. {  
  232.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  233.       
  234.     DLinkCircleListNode* ret = NULL;  
  235.       
  236.     if(NULL!=sList)  
  237.     {  
  238.         ret = sList->slider;  
  239.     }  
  240.       
  241.     return ret;  
  242. }  
  243.   
  244. DLinkCircleListNode* DLinkCircleList_Next(DLinkCircleList* list)  
  245. {  
  246.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  247.       
  248.     DLinkCircleListNode* ret = NULL;  
  249.       
  250.     if((NULL!=sList)&&(NULL!=sList->slider))  
  251.     {  
  252.         ret = sList->slider;  
  253.         sList->slider = ret->next;  
  254.     }  
  255.       
  256.     return ret;  
  257. }  
  258.   
  259. DLinkCircleListNode* DLinkCircleList_Pre(DLinkCircleList* list)  
  260. {  
  261.     TDLinkCircleList* sList = (TDLinkCircleList*)list;  
  262.       
  263.     DLinkCircleListNode* ret = NULL;  
  264.       
  265.     if((NULL!=sList)&&(NULL!=sList->slider))  
  266.     {  
  267.         ret = sList->slider;  
  268.         sList->slider = ret->pre;  
  269.     }  
  270.       
  271.     return ret;  
  272. }  


 

Main.c :

[cpp] view plain copy


  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include “DLinkCircleList.h”  
  4.   
  5. typedef struct _tag_Value  
  6. {  
  7.     DLinkCircleListNode header;  
  8.     int v;  
  9. }Value;  
  10.   
  11. int main(void)  
  12. {  
  13.     DLinkCircleList* list = DLinkCircleList_Create();  
  14.       
  15.     Value v1,v2,v3,v4,v5;  
  16.       
  17.     Value* pV = NULL;  
  18.       
  19.     int i = 0;  
  20.       
  21.     v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;  
  22.       
  23.     DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v1, DLinkCircleList_Length(list));  
  24.     DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v2, DLinkCircleList_Length(list));  
  25.     DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v3, DLinkCircleList_Length(list));  
  26.     DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v4, DLinkCircleList_Length(list));  
  27.     DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v5, DLinkCircleList_Length(list));  
  28.       
  29.     for(i=0; i<DLinkCircleList_Length(list); i++)  
  30.     {  
  31.         pV = (Value*)DLinkCircleList_Get(list, i);  
  32.           
  33.         printf(”已发现节点:%d\n”, pV->v);  
  34.     }  
  35.     printf(”\n”);  
  36.       
  37.     DLinkCircleList_Delete(list, 0);  
  38.     DLinkCircleList_DeleteNode(list, &v3);  
  39.       
  40.     DLinkCircleList_Destroy(list);  
  41.       
  42.     return 0;  
  43. }  
原创粉丝点击