数据结构体模版---循环单链表

版权声明:本文为博主原创文章 && 转载请著名出处 @ http://blog.csdn.net/gatieme

[cpp] view plain copy print?

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <stdbool.h>  
  4. #include <assert.h>  
  5.   
  6. //#define DEBUG             // 调试插桩信息宏  
  7.   
  8. ///*////////////////////////////////////////////////////////////////////////////  
  9. ///  
  10. /// 带头结点的单链表结构体  
  11. ///  
  12. ///*////////////////////////////////////////////////////////////////////////////  
  13. typedef int ElemType;       // 自定义数据类型  
  14.   
  15. //typedef struct CirLinkListNode*   PCirLinkListNode;           // 链表结点指针域  
  16.   
  17. // 链表结点数据域  
  18. typedef struct CirLinkListNode  
  19. {  
  20.     ElemType                m_data;         // 数据域  
  21.     struct CirLinkListNode  *m_next;        // 指针域  
  22. }CirLinkListNode;  
  23.   
  24. // 带头结点的单项链表  
  25. typedef struct CirLinkList  
  26. {  
  27.     CirLinkListNode *m_head;                // 链表头结点  
  28.     CirLinkListNode *m_tail;                // 循环链表尾部  
  29.     int             m_length;               // 单链表数据结点个数指针域  
  30. //  this->m_head == this->m_tail->m_next;  // 如果只设尾结点要理解此等价关系  
  31. }CirLinkList;  
  32.   
  33.   
  34.   
  35. ///*////////////////////////////////////////////////////////////////////////////  
  36. ///  
  37. /// 创建和初始化单链表  
  38. ///  
  39. /// 开辟一个单链表数据结构,并初始化头结点,然后将创建好的单链表指针返回  
  40. /// CirLinkList* CreatCirLinkList(void)  
  41. ///  
  42. /// 初始化单链表  
  43. /// void InitCirLinkList(CirLinkList *list)  
  44. ///*///////////////////////////////////////////////////////////////////////////  
  45.   
  46. /** 
  47. CirLinkList* CreatCirLinkList(void) 
  48. 参数 
  49.     list    :   指向一个链表指针,此处传入表头地址 
  50. 返回值 
  51.     若成功返回创建好的单链表的指针 
  52. 功能 
  53.     开辟一个单链表数据结构,并初始化头结点,然后将创建好的单链表指针返回 
  54. 注意 
  55.     使用CreateCirLinkList创建的单链表,需要用DestroyCirLinkList来销毁 
  56.     以免发生内存泄漏 
  57. */  
  58. CirLinkList* CreateCirLinkList(void)  
  59. {  
  60.     CirLinkList *list = NULL;  
  61.     if((list = (CirLinkList *)malloc(sizeof(CirLinkList))) == NULL)     // 开辟单链表的空间  
  62.     {   // 开辟失败  
  63.         fprintf(stderr, "not enough memory when CREATE LIST...\n");  
  64.         exit(EXIT_FAILURE);  
  65.     }  
  66.   
  67.     InitCirLinkList(list);              // 初始化单链表  
  68.   
  69.     return list;  
  70. }  
  71.   
  72.   
  73.   
  74. /** 
  75. void InitCirLinkList(CirLinkList *list) 
  76. 参数 
  77.     list    :   指向一个链表指针,此处传入表头地址 
  78. 返回值 
  79.     无 
  80. 功能 
  81.     初始化单链表, 执行以下操作 
  82.     ①开辟头结点的空间 ②进行必要的初始化[头结点的初始化和单链表结点数目的初始化] 
  83. 注意 
  84.     使用InitCirLinkList初始化的单链表(初始化时malloc了头结点m_head的空间) 
  85.     而使用用FinitCirLinkList来进行后处理(后处理时free了头结点的m_head空间) 
  86.     以免发生内存泄漏 
  87. */  
  88. void InitCirLinkList(CirLinkList *list)  
  89. {  
  90.     if((list->m_head = malloc(sizeof(CirLinkListNode))) == NULL)     // 为头结点开辟空间  
  91.     {   // 开辟失败  
  92.         fprintf(stderr, "not enough memory when MALLOC HEAD...");  
  93.         exit(EXIT_FAILURE);  
  94.     }  
  95.   
  96.     // 初始化头结点信息  
  97.     list->m_head->m_next = list->m_head;   // 初始化只有头结点[空循环链表的特征]  
  98.     list->m_head->m_data = 0;             // 数据元素个数为0  
  99.     list->m_length = 0;                      // 数据元素个数为0  
  100.     list->m_tail = list->m_head;          // 尾指针指向头结点  
  101. }  
  102.   
  103. ///*////////////////////////////////////////////////////////////////////////////  
  104. ///  
  105. /// 销毁以及后处理单链表  
  106. ///  
  107. /// 销毁用CreateCirLinkList创建的单链表  
  108. /// void DestroyCirLinkList(CirLinkList *list)  
  109. ///  
  110. /// 后处理单链表,  
  111. /// void FinitCirLinkList(CirLinkList *list)  
  112. ///  
  113. /// 清空单链表中的所有元素  
  114. /// void ClearCirLinkList(CirLinkList *list)  
  115. ///*////////////////////////////////////////////////////////////////////////////  
  116.   
  117. /** 
  118. void DestroyCirLinkList(CirLinkList *list) 
  119. 参数 
  120.     list    :   指向一个链表指针,此处传入表头地址 
  121. 返回值 
  122.     无 
  123. 功能 
  124.     销毁用CreateCirLinkList创建的单链表,执行以下操作 
  125.     ①清空单链表  ②释放头结点  ③释放单链表 
  126. 注意 
  127.     使用CreateCirLinkList创建的单链表,需要用DestroyCirLinkList来销毁 
  128.     以免发生内存泄漏 
  129. */  
  130. CirLinkList* DestroyCirLinkList(CirLinkList *list)  
  131. {  
  132.     ClearCirLinkList(list);         // 清空链表  
  133.     FinitCirLinkList(list);         // 销毁头结点  
  134.     if(list != NULL)                // 销毁链表的空间  
  135.     {  
  136.         free(list);  
  137.         list = NULL;  
  138.     }  
  139. }  
  140.   
  141.   
  142.   
  143.   
  144.   
  145. /** 
  146. void FinitCirLinkList(CirLinkList *list) 
  147. 参数 
  148.     list    :   指向一个链表指针,此处传入表头地址 
  149. 返回值 
  150.     无 
  151. 功能 
  152.     后处理单链表, 执行以下操作 
  153.     ①开辟头结点的空间 ②进行必要的初始化[头结点的初始化和单链表结点数目的初始化] 
  154. 注意 
  155.     使用InitCirLinkList初始化的单链表(初始化时malloc了头结点m_head的空间) 
  156.     而使用用FinitCirLinkList来进行后处理(后处理时free了头结点的m_head空间) 
  157.     以免发生内存泄漏 
  158. */  
  159. void FinitCirLinkList(CirLinkList *list)  
  160. {  
  161.     assert(list->m_head->m_next == list->m_head);      // 后处理指针针对空链表  
  162.     // assert(list->m_length == 0);  
  163.     if(list->m_head != NULL)         // 如果此时头结点空间未被销毁  
  164.     {  
  165.         free(list->m_head);  
  166.   
  167.         list->m_head = NULL;  
  168.         list->m_length = -1;         // 未经初始化的单链表元素个数记为-1  
  169.     }  
  170. }  
  171.   
  172.   
  173.   
  174. /** 
  175. void ClearCirLinkList(CirLinkList *list) 
  176. 参数 
  177.     list    :   指向一个链表指针,此处传入表头地址 
  178. 返回值 
  179.     无 
  180. 功能 
  181.     清空单链表中的所有元素 
  182. */  
  183. void ClearCirLinkList(CirLinkList *list)  
  184. {  
  185.     while(list->m_head->m_next != list->m_head)  
  186.     {  
  187.         DeleteNode(list, 0);  
  188.     }  
  189. }  
  190.   
  191. ///*////////////////////////////////////////////////////////////////////////////  
  192. ///  
  193. /// 查找函数  
  194. ///  
  195. /// 查找到链表list中第position个结点  
  196. /// CirLinkListNode* FindPosNode(CirLinkList *list, int position)  
  197. ///  
  198. /// 在链表list中找到currNode的前一个结点  
  199. /// CirLinkListNode *FindPrevNode(CirLinkList *list, CirLinkListNode *currNode)  
  200. ///  
  201. /// 判断结点node指向的区域是不是链表中的结点  
  202. /// int IsNodeInList(CirLinkList *list, CirLinkListNode *node)  
  203. ///  
  204. /// 找到数据域为data的结点首次出现的位置并返回结点信息  
  205. /// CirLinkListNode* FindDataNode(CirLinkList *list, ElemType data, int *position)  
  206. ///*////////////////////////////////////////////////////////////////////////////  
  207. /** 
  208. CirLinkListNode* FindPosNode(CirLinkList *list, int position) 
  209.  
  210. 参数 
  211.     list    :   指向一个链表指针,此处传入表头地址 
  212.     positon :   带查找的链表指针的位置 
  213. 返回值 
  214.     若成功返回指向待查找结点的指针 
  215.     若失败返回NULL 
  216. 功能 
  217.     该函数的功能是:    查找到链表list中第position个结点 
  218. */  
  219. CirLinkListNode* FindPosNode(CirLinkList *list, int position)  
  220. {  
  221.     assert(list != NULL);                                   // 链表不能为空  
  222.     assert(position >= -1 && position < list->m_length);   // 插入的w位置只能在[-1~length]  
  223.   
  224.     CirLinkListNode     *pNode  = list->m_head->m_next;  
  225. //  CirLinkListNode *pNode = list->m_tail->m_next;            // 当循环链表只设尾指针时采用此代码  
  226.   
  227.     if(position == -1)                                          // -1表示寻找头指针的前驱  
  228.     {  
  229.         return list->m_head;                             // 直接返回前驱  
  230.     }  
  231.   
  232.     int             pos     = 0;  
  233.   
  234.     while(pNode != list->m_head && pos < position)        // 遍历单链表,找到第position个结点的位置  
  235.     {  
  236.         pNode = pNode->m_next;  
  237.         pos++;  
  238.     }  
  239.   
  240.     if(pos < position)       // 如果找到链表尾部还没有找到  
  241.     {  
  242.         return NULL;  
  243.     }  
  244.     else  
  245.     {  
  246. #ifdef DEBUG  
  247.         printf("Find the %d point SUCCESS...[%p]\n", position, pNode);  
  248. #endif // DEBUG  
  249.         return pNode;  
  250.     }  
  251. }  
  252.   
  253. /** 
  254. CirLinkListNode *FindPrevNode(CirLinkList *list, CirLinkListNode *currNode); 
  255.  
  256. 参数 
  257.     list        :   指向一个链表指针,此处传入表头地址 
  258.     currNode    :   待查找的链表指针的位置 
  259. 返回值 
  260.     若成功返回指向待查找结点的指针 
  261.     若失败返回NULL 
  262. 功能 
  263.     在链表list中找到currNode的前一个结点 
  264. */  
  265.   
  266. CirLinkListNode *FindPrevNode(CirLinkList *list, CirLinkListNode *currNode)  
  267. {  
  268.     assert(list !=  NULL);  
  269.     assert(currNode != NULL);  
  270.   
  271.     CirLinkListNode *pNode = list->m_head;  
  272. //  CirLinkListNode *pNode = list->m_tail->m_next;            // 当循环链表只设尾指针时采用此代码  
  273.   
  274.     while(pNode->m_next != list->m_head && pNode->m_next != currNode)  
  275.     {  
  276.         pNode = pNode->m_next;  
  277.     }  
  278.   
  279.     if(pNode->m_next == currNode)                // 查找成功  
  280.     {  
  281.         return pNode;  
  282.     }  
  283.     else                                        // 查找失败  
  284.     {  
  285.         return NULL;  
  286.     }  
  287. }  
  288.   
  289.   
  290.   
  291. /** 
  292. int IsNodeInList(CirLinkList *list, CirLinkListNode *node) 
  293.  
  294. 参数 
  295.     list    :   指向一个链表指针,此处传入表头地址 
  296.     node    :   指向待查找的结点的指针 
  297. 返回值 
  298.     若成功 返回结点node在链表中的位置 
  299.     若失败 返回-1 
  300. 功能 
  301.     判断结点node指向的区域是不是链表中的结点 
  302. */  
  303. int IsNodeInList(CirLinkList *list, CirLinkListNode *node)  
  304. {  
  305.     assert(list != NULL);                                   // 链表不能为空   assert(Node != NULL);                                   // 待查找的指针不能为空  
  306.   
  307.     CirLinkListNode     *pNode  = list->m_head->m_next;  
  308. //  CirLinkListNode *pNode = list->m_tail->m_next;            // 当循环链表只设尾指针时采用此代码  
  309.     int             pos     = 0;  
  310.   
  311.     while(pNode != list->m_head && pNode != node)        // 遍历单链表,找到第position个结点的位置  
  312.     {  
  313.         pNode = pNode->m_next;  
  314.         pos++;  
  315.     }  
  316.   
  317.     if(pNode != node)  
  318.     {   // 查找成功  
  319.         return -1;  
  320.     }  
  321.     else  
  322.     {   // 查找失败  
  323. #ifdef DEBUG  
  324.         printf("Find the [%p] point in the first %d pointer of the list...\n", fNode, pos);  
  325. #endif // DEBUG  
  326.         return pos;  
  327.     }  
  328. }  
  329.   
  330.   
  331. /** 
  332. CirLinkListNode* FindDataNode(CirLinkList *list, ElemType data, int *position 
  333.  
  334. 参数 
  335.     list    :   指向一个链表指针,此处传入表头地址 
  336.     data    :   待查找的结点的数据信息 
  337. 返回值 
  338.     若成功 返回结点node在链表中的位置 
  339.     若失败 返回-1 
  340. 功能 
  341.     找到数据域为data的结点首次出现的位置并返回结点信息 
  342. */  
  343. CirLinkListNode* FindDataNode(CirLinkList *list, ElemType data, int *position)  
  344. {  
  345.     CirLinkListNode *node = list->m_head->m_next;  
  346. //  CirLinkListNode *pNode = list->m_tail->m_next;            // 当循环链表只设尾指针时采用此代码  
  347.   
  348.     int pos = 0;  
  349.     while(node != list->m_head && node->m_data != data)  
  350.     {  
  351.         node = node->m_next;  
  352.         pos++;  
  353.     }  
  354.     *position = pos;                // 将出现的位置传递回去  
  355.   
  356.     return node;                    // 返回结点的信息  
  357. }  
  358.   
  359.   
  360. ///*////////////////////////////////////////////////////////////////////////////  
  361. ///  
  362. /// 插入函数  
  363. ///  
  364. /// 将数据data插入链表的prevNode结点的下一个位置个位置  
  365. /// CirLinkListNode *AddNode(CirLinkList *list, CirLinkListNode *prevNode, ElemType data)  
  366. ///  
  367. /// 将数据data插入链表的第position个位置  
  368. /// CirLinkListNode *InsertNode(CirLinkList *list, int position, ElemType data)  
  369. ///*////////////////////////////////////////////////////////////////////////////  
  370.   
  371.   
  372. /** 
  373. CirLinkListNode* AddNode(CirLinkList *list, CirLinkListNode *prevNode, ElemType data); 
  374. 参数 
  375.     list        :   指向一个链表指针,此处传入表头地址 
  376.     prevNode    :   待插入位置的前一个结点 
  377.     data        :   待插入结点的数据 
  378. 返回值 
  379.     无 
  380. 功能 
  381.     该函数的功能是:    将数据data插入链表的prevNode结点的下一个位置个位置 
  382. */  
  383. CirLinkListNode* AddNode(CirLinkList *list, CirLinkListNode *prevNode, ElemType data)  
  384. {  
  385.     assert(prevNode != NULL);                       // 插入点不能是空指针  
  386.   
  387.     CirLinkListNode *newNode = NULL;  
  388.   
  389.     if((newNode = (CirLinkListNode *)malloc(sizeof(CirLinkListNode))) == NULL)  // 为新结点开辟空间  
  390.     {   // 开辟新结点失败  
  391.         fprintf(stderr, "not enough memeory\n");  
  392.         exit(EXIT_FAILURE);  
  393.     }  
  394.     else  
  395.     {  
  396.         // 开辟新结点成功  
  397.         newNode->m_data = data;  
  398.         newNode->m_next = NULL;  
  399.     }  
  400.   
  401.     // 将指针newNode连接在pNode的后面  
  402.     newNode->m_next = prevNode->m_next;  
  403.     prevNode->m_next = newNode;  
  404.   
  405.     list->m_length++;                // 结点数目增加一个  
  406.     list->m_head->m_data++;           // 头结点的数据域同样存储着结点总数  
  407.     //}  
  408. #ifdef DEBUG  
  409.     printf("The new node is inserted after point pointer[%p]\n", pNode);  
  410. #endif // DEBUG  
  411.     return newNode;  
  412. }  
  413.   
  414.   
  415. /** 
  416. void InsertNode(CirLinkList *list, int position, ElemType data) 
  417. 参数 
  418.     list    :   指向一个链表指针,此处传入表头地址 
  419.     positon :   待插入结点的位置 
  420.     data    :   待插入结点的数据 
  421. 返回值 
  422.     无 
  423. 功能 
  424.     该函数的功能是:    将数据data插入链表的第position个位置 
  425. */  
  426. CirLinkListNode* InsertNode(CirLinkList *list, int position, ElemType data)  
  427. {  
  428.     assert(list != NULL);  
  429.     assert(position >=0 && position < list->m_length + 1);  
  430.   
  431.     CirLinkListNode *prevNode = FindPosNode(list, position - 1);            // 找到待插入位置的前一个结点  
  432.     CirLinkListNode *newNode = NULL;  
  433.   
  434.     // 下面调用InsertPointNode直接将结点插入到pNode结点后面  
  435.     if((newNode = AddNode(list, prevNode, data)) != NULL)   // 将新的结点插入到待插入前一个指针的后面  
  436.     {   // 插入成功  
  437.         return newNode;                             // 返回新插入的结点  
  438. #ifdef DEBUG  
  439.         printf("Insert the value %d into list at position %d...\n", data, position);  
  440. #endif // DEBUG  
  441.     }  
  442.     else  
  443.     {  
  444.         return NULL;                                // 插入失败返回NULL  
  445.     }  
  446.   
  447. //  //  以可以使用下面的代码  
  448. //  if((newNode = (CirLinkListNode *)malloc(sizeof(CirLinkListNode))) == NULL)  // 为新结点开辟空间  
  449. //  {   // 开辟新结点失败  
  450. //      fprintf(stderr, "not enough memeory\n");  
  451. //        exit(EXIT_FAILURE);  
  452. //  }  
  453. //  else  
  454. //  {   // 开辟新结点成功  
  455. //  newNode->m_data = data;  
  456. //  newNode->m_next = NULL;  
  457. //  
  458. //  // 将指针newNode连接在pNode的后面  
  459. //  newNode->m_next = prevNode->m_next;  
  460. //  prevNode->m_next = newNode;  
  461. //  
  462. //  list->m_length++;                // 结点数目增加一个  
  463. //  list->m_head->m_data++;           // 头结点的数据域同样存储着结点总数  
  464. //  }  
  465. }  
  466.   
  467.   
  468. ///*////////////////////////////////////////////////////////////////////////////  
  469. ///  
  470. /// 删除函数  
  471. ///  
  472. /// 删除链表list中prevNode结点之后的指针个指针  
  473. /// void DeleteNode(CirLinkList *list, int position)  
  474. ///  
  475. /// 删除链表list中prevNode结点之后的指针个指针  
  476. /// ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode)  
  477. ///  
  478. /// 删除链表list中prevNode结点之后的指针个指针  
  479. /// ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode)  
  480. ///*////////////////////////////////////////////////////////////////////////////  
  481.   
  482. /** 
  483. void DeleteNode(CirLinkList *list, int position) 
  484. 参数 
  485.     list    :   指向一个链表指针,此处传入表头地址 
  486.     positon :   待删除结点的位置 
  487. 返回值 
  488.     返回待删除结点的数据域 
  489. 功能 
  490.     将单链表的第position个结点删除 
  491. */  
  492. ElemType DeleteNode(CirLinkList *list, int position)  
  493. {  
  494.     assert(list != NULL);  
  495.     assert(position >=0 && position < list->m_length);  
  496.     CirLinkListNode *prevNode = FindPosNode(list, position - 1);            // 找到第position - 1个结点  
  497.   
  498.     // 删除pNode的后一个结点  
  499.     CirLinkListNode *delNode = prevNode->m_next;  
  500.     ElemType delElem = delNode->m_data;  
  501.     prevNode->m_next = delNode->m_next;  
  502.     free(delNode);  
  503.   
  504.     list->m_length--;                // 结点数目减少一个  
  505.     list->m_head->m_data--;           // 头结点的数据域同样存储着结点总数  
  506.   
  507.     return delElem;  
  508. }  
  509.   
  510.   
  511. /** 
  512. ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode) 
  513. 参数 
  514.     list    :   指向一个链表指针,此处传入表头地址 
  515.     positon :   待删除结点的位置 
  516. 返回值 
  517.     返回待删除结点的数据域 
  518. 功能 
  519.     删除链表list中prevNode结点之后的指针个指针 
  520. */  
  521. ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode)  
  522. {  
  523.     assert(list != NULL);                       // 链表不能为空  
  524.     assert(prevNode != NULL);                       // 待删除结点的前一个位置不能为空  
  525.     assert(IsNodeInList(list, prevNode) != -1); // 待删除位置的前一个结点必须在链表中  
  526.   
  527.     // 删除pNode的后一个结点  
  528.     CirLinkListNode *delNode = prevNode->m_next;  
  529.     ElemType delElem = delNode->m_data;  
  530.     prevNode->m_next = delNode->m_next;  
  531.     free(delNode);  
  532.   
  533.     list->m_length--;                // 结点数目减少一个  
  534.     list->m_head->m_data--;           // 头结点的数据域同样存储着结点总数  
  535.   
  536.     return delElem;  
  537. }  
  538.   
  539.   
  540.   
  541. /** 
  542. ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode); 
  543. 参数 
  544.     list    :   指向一个链表指针,此处传入表头地址 
  545.     positon :   待删除结点的位置 
  546. 返回值 
  547.     返回待删除结点的数据域 
  548. 功能 
  549.     删除链表list中prevNode结点之后的指针个指针 
  550. */  
  551. ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode)  
  552. {  
  553.     assert(list != NULL);                           // 链表不能为空  
  554.     assert(currNode != NULL);                           // 待删除结点的前一个位置不能为空  
  555.     assert(IsNodeInList(list, currNode) != -1); // 待删除的结点必须在链表中  
  556.   
  557.     ElemType            delElem = -1;                           // 待删除结点的数据域  
  558.     CirLinkListNode     *delNode = NULL;                    // 指向将要删除的结点的指针  
  559.   
  560. //  if(list->m_length == 0)  
  561. //  {  
  562. //  
  563. //      return -1;  
  564. //  }  
  565. //  printf("length = %d\n", list->m_length);  
  566.     if(currNode->m_next != list->m_head)                  // 如果待删除结点不是最后一个结点  
  567.     {  
  568.         // 将currNode的后一个结点delNode作为删除结点,  
  569.         delNode = currNode->m_next;  
  570.         currNode->m_next = delNode->m_next;           //从链表中删除delNode  
  571.   
  572.         // 并将delNode的数据域保存到delNode中  
  573.         delElem = currNode->m_data;                  // delElem保存currNode的数据域  
  574.         currNode->m_data = delNode->m_data;           // 真正删除的结点其实是currNode下一个结点, 因此用currNode保存下一个结点的数据域  
  575.     }  
  576.     else                                            // 否则待删除结点是最后一个结点  
  577.     {  
  578.         // 直接将最后一个结点删除即可, 应该把其前一个结点的指针域赋值为空  
  579.         delNode = currNode;  
  580.         // 下面应该将currnNode的前一个结点的指针域赋值为空[时间复杂度O(n)]  
  581.         CirLinkListNode *prevNode = FindPrevNode(list, currNode);  
  582.         prevNode->m_next = list->m_head;          /// BUG1  最后一个结点的后一个结点  
  583.     }  
  584.     free(delNode);  
  585.     list->m_length--;                // 结点数目减少一个  
  586.     list->m_head->m_data--;           // 头结点的数据域同样存储着结点总数  
  587.   
  588.     return delElem;  
  589. }  
  590.   
  591.   
  592.   
  593.   
  594. ///*////////////////////////////////////////////////////////////////////////////  
  595. ///  
  596. /// 其他函数  
  597. ///  
  598. /// 显示单链表的信息  
  599. /// void ShowList(CirLinkList *list  
  600. ///  
  601. /// 删除链表list中prevNode结点之后的指针个指针  
  602. /// void SetNode(CirLinkList *list, int position, ElemType data)  
  603. ///  
  604. /// 获取单链表list第position个结点的数据域  
  605. /// ElemType GetNode(CirLinkList *list, int position)  
  606. ///  
  607. /// 获取单链表list的长度[即元素个数]  
  608. /// int LengthCirLinkList(CirLinkList *list)  
  609. ///  
  610. /// 判断当前链表是否是空链表  
  611. /// bool IsEmptyCirLinkList(CirLinkList *list)  
  612. ///*////////////////////////////////////////////////////////////////////////////  
  613.   
  614. /** 
  615. void ShowCirLinkList(CirLinkList *list) 
  616. 参数 
  617.     list    :   指向一个链表指针,此处传入表头地址 
  618. 返回值 
  619.     无 
  620. 功能 
  621.     显示单链表的信息 
  622. */  
  623. void ShowList(CirLinkList *list)  
  624. {  
  625. // assert(list->m_head != NULL)  
  626.     if(list->m_head ==  NULL)            //  单链表可能没有被初始化  
  627.     {  
  628.         fprintf(stderr, "you can't SHOW the list without the list INITLINKLIST...\n");  
  629.         return ;  
  630.     }  
  631.   
  632.   
  633.     printf("there are %d data in list\n", list->m_length);  
  634.     if(list->m_length == 0)  
  635.     {  
  636.         return ;  
  637.     }  
  638.   
  639.     CirLinkListNode *pNode = list->m_head->m_next;            // 从头指针开始遍历  
  640.   
  641.     while(pNode != list->m_head)                             //开始遍历单链表  
  642.     {  
  643.         printf("%d  ", pNode->m_data);  
  644.         pNode = pNode->m_next;  
  645.     }  
  646.     printf("\n");  
  647.   
  648. //  ElemType data;  
  649. //  for(int pos = 0; pos < list->m_length; pos++)  
  650. //  {  
  651. //      data = GetNode(list, pos);  
  652. //      printf("%d  ", data);  
  653. //  }  
  654. //  printf("\n");  
  655. }  
  656.   
  657. /** 
  658. void SetNode(CirLinkList *list, int position, ElemType data) 
  659. 参数 
  660.     list    :   指向一个链表指针,此处传入表头地址 
  661.     positon :   待修改的结点的数据 
  662.     data    :   待更正的新数据域 
  663. 返回值 
  664.     无 
  665. 功能 
  666.     修改单链表list第position个结点的数据域为data 
  667. */  
  668. void SetNode(CirLinkList *list, int position, ElemType data)  
  669. {  
  670.     CirLinkListNode *pNode = FindPosNode(list, position);       // 找到单链表的第position个结点  
  671.   
  672.     pNode->m_data = data;  
  673. }  
  674.   
  675. /** 
  676. ElemType GetNode(CirLinkList *list, int position 
  677. 参数 
  678.     list    :   指向一个链表指针,此处传入表头地址 
  679.     positon :   待查询的结点的位置 
  680. 返回值 
  681.     获取到的结点数据 
  682. 功能 
  683.     获取单链表list第position个结点的数据域 
  684. */  
  685. ElemType GetNode(CirLinkList *list, int position)  
  686. {  
  687.     CirLinkListNode *pNode = FindPosNode(list, position);       // 找到单链表的第position个结点  
  688.   
  689.     return pNode->m_data;  
  690. }  
  691.   
  692.   
  693. /** 
  694. int LengthCirLinkList(CirLinkList *list) 
  695. 参数 
  696.     list    :   指向一个链表指针,此处传入表头地址 
  697. 返回值 
  698.     单链表的长度 
  699. 功能 
  700.     获取单链表的长度 
  701. */  
  702. int LengthCirLinkList(CirLinkList *list)  
  703. {  
  704.     return list->m_length;  
  705. }  
  706.   
  707.   
  708. /** 
  709. bool IsEmptyCirLinkList(CirLinkList *list) 
  710. 参数 
  711.     list    :   指向一个链表指针,此处传入表头地址 
  712. 返回值 
  713.     如果单链表是空表,返回true 
  714.     否则返回false 
  715. 功能 
  716.     获取单链表的长度 
  717. */  
  718. bool IsEmptyCirLinkList(CirLinkList *list)  
  719. {  
  720.     return (list->m_head->m_next == list->m_head);  
  721. //  return (list->m_tail == this->m_head);  
  722. }  
  723.   
  724.   
  725. /** 
  726. CirLinkListNode* GetFisrtNode(CirLinkList *list) 
  727. 参数 
  728.     list    :   指向一个链表指针,此处传入表头地址 
  729. 返回值 
  730.     返回头指针 
  731. 功能 
  732.     获取循环链表的头指针 
  733. */  
  734. CirLinkListNode* GetFisrtNode(CirLinkList *list)  
  735. {  
  736.     return list->m_head->m_next;  
  737. //  return list->m_tail->m_next->m_next;           // 只设尾指针的时候使用此代码  
  738. }  
  739.   
  740.   
  741. /** 
  742. CirLinkListNode* GetHeadNode(CirLinkList *list) 
  743. 参数 
  744.     list    :   指向一个链表指针,此处传入表头地址 
  745. 返回值 
  746.     返回头结点的地址 
  747. 功能 
  748.     获取指向头结点的指针 
  749. */  
  750. CirLinkListNode* GetHeadNode(CirLinkList *list)  
  751. {  
  752.     return list->m_head;  
  753. //  return list->m_tail->m_next;          // 只设尾指针的时候使用此代码  
  754. }  
  755.   
  756.   
  757.   
  758.   
  759.   
  760.   
  761. #define LIST_SIZE 7  
  762. // 主函数  
  763. int main(void)  
  764. {  
  765.     int pos;  
  766.   
  767.     printf("TEST 1...\n");  
  768.     CirLinkList *plist = CreateCirLinkList( );              // 创建单链表  
  769.     for(int pos = 0; pos < LIST_SIZE; pos++)         // 循环向单链表中插入数据  
  770.     {  
  771.         InsertNode(plist, pos, pos + 1);  
  772.     }  
  773.     ShowList(plist);                                    // 插入结束后显示单链表的信息  
  774.   
  775.     DeleteNode(plist, 0);                               // 删除第一个元素  
  776.     ShowList(plist);  
  777.     DeleteNode(plist, 1);                               // 删除第二个元素  
  778.     ShowList(plist);  
  779.   
  780.     ClearCirLinkList(plist);                                // 将单链表清空  
  781.     ShowList(plist);  
  782.     DestroyCirLinkList(plist);                              // 将单链表销毁  
  783.     plist = NULL;  
  784.   
  785.     printf("\n\nTEST 2...\n");  
  786.     CirLinkList list;  
  787.     InitCirLinkList(&list);                             // 初始化单链表  
  788.     for(int pos = 0; pos < LIST_SIZE; pos++)         // 训话向单链表中插入数据  
  789.     {  
  790.         InsertNode(&list, pos, pos + 1);  
  791.     }  
  792.     ShowList(&list);                                    // 显示单链表  
  793.     ClearCirLinkList(&list);                                // 清空单链表  
  794. //  FinitLinkList(&list);       // ERROR== list->m_head->m_next == NULL  
  795.     ShowList(&list);  
  796.   
  797.     printf("\n\nTEST 3...\n");  
  798.     CirLinkListNode *prevNode = list.m_head;  
  799.     CirLinkListNode *addNode = NULL;  
  800.     for(int pos = 0; pos < LIST_SIZE; pos++)  
  801.     {  
  802.         if((addNode = AddNode(&list, prevNode, pos + 1)) != NULL)  
  803.         {  
  804.             prevNode = addNode;  
  805.         }  
  806.     }  
  807.     ShowList(&list);  
  808.     while(IsEmptyCirLinkList(&list) != true)            // 循环删除单链表中的数据  
  809.     {  
  810.         //printf("%p == %p\n", list.m_head->m_next, list.m_head);  
  811.         DeleteCurrNode(&list, list.m_head->m_next);  
  812.     }  
  813.     ShowList(&list);                                    // 显示单链表  
  814.   
  815.     return  EXIT_SUCCESS;  
  816. }  

转载:http://blog.csdn.net/gatieme/article/details/42714079

时间: 2024-10-29 21:27:35

数据结构体模版---循环单链表的相关文章

数据结构之自建算法库——循环单链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时循环链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:clinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CLINKLIST_H_INCLUDED #define CLINKLIST_H_INCLUDED //循环单链表基本运算函数 typedef int Elem

数据结构算法设计: 请设计一个算法,统计一个循环单链表L中的结点个数。

问题描述 数据结构算法设计: 请设计一个算法,统计一个循环单链表L中的结点个数. 算法设计: 请设计一个算法,统计一个循环单链表L中的结点个数. 解决方案 int n = 0; while (L != NULL) { L = L->next; n++; } 解决方案二: /* counts the nodes in the list / int fuc(struct list head) { void *tmp; int i; if(!head) return -1; for(i = 1, tm

c++ 数据结构-数据结构c++循环单链表问题,急!!

问题描述 数据结构c++循环单链表问题,急!! CirSinglyList& operator+=(CirSinglyList &list) //尾插入list,集合并 解决方案 CirSinglyList& operator+=(CirSinglyList &list) { CirSinglyList *p = this; while(p->next != NULL) p = p->next; while(list->next != NULL) { p-

c++ 数据结构-数据结构c++单链表问题 急!!

问题描述 数据结构c++单链表问题 急!! 5C SinglyList& operator*=(SinglyList &list) //仅保留那些也包含在list中的元素,集合交 解决方案 单链表逆序的C++实现 解决方案二: http://ask.csdn.net/questions/253462

为什么不允许删除循环单链表中最后一个结点?如何解决?

问题描述 为什么不允许删除循环单链表中最后一个结点?如何解决? /*****************************************************/ /* 函数功能:建立一个空的循环单链表 / / 函数参数:无 / / 函数返回值:指向node类型变量的指针 / / 文件名:clnkinit.c,函数名init() / /****************************************************/ node init() /建立一个空的循环

@数据结构大神,单链表的插入,56行怎么错了?求解释~

问题描述 @数据结构大神,单链表的插入,56行怎么错了?求解释~ include include typedef struct Node { char data; struct Node *next; }Node,*Linklist;//先定义.后使用 //定义数据L-分配头节点-插入数据,连-接-返回 Linklist Createfromhead() { Linklist L;Node*s;int flag=1;char c; L=(Linklist)malloc(sizeof(Node))

数据结构学习(C++)之单链表

节点类 #ifndef Node_H#define Node_Htemplate <class Type> class Node //单链节点类{ public: Type data; Node<Type> *link; Node() : data(Type()), link(NULL) {} Node(const Type &item) : data(item), link(NULL) {} Node(const Type &item, Node<Type&

c++ 数据结构-实现以下对单链表的操作,要求单链表一次遍历效率(数据结构c++)

问题描述 实现以下对单链表的操作,要求单链表一次遍历效率(数据结构c++) double averageExceptMaxMin(SinglyList &list) ?//去掉最高分和最低分,再求平均值 解决方案 double averageExceptMaxMin(SinglyList &list){ double d = 0.0; int n = 0; double max = 0.0; double min = 0.0; Node * node = &list.head; w

数据结构C#版笔记--单链表(LinkList)

上一篇学习了"顺序表(SeqList)",这一篇来看下"单链表(LinkList)".在上一篇的最后,我们指出了:顺序表要求开辟一组连续的内存空间,而且插入/删除元素时,为了保证元素的顺序性,必须对后面的元素进行移动.如果你的应用中需要频繁对元素进行插入/删除,那么开销会很大.   而链表结构正好相反,先来看下结构: 每个元素至少具有二个属性:data和next.data用来存放数据,而next用来指出它后面的元素是谁(有点"指针"的意思). 链