数据结构模版----单链表SimpleLinkList[带头结点](C语言实现)

简介:

前面写的单链表结构体是重新设计的。包含头结点(或者头指针)以及链表长度的结构体,而我们通常实现的链表是直接把单链表结点结构体作为单链表来使用的,下面我们给出z这种实现方式,让我们一起来细细体会他们实现之间的区别

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


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

目录
相关文章
|
26天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
38 1
|
1月前
|
存储 算法 搜索推荐
【趣学C语言和数据结构100例】91-95
本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
46 4
|
1月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
43 4
|
1月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
41 4
|
1月前
|
算法 数据可视化 数据建模
【趣学C语言和数据结构100例】76-80
本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
51 4
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
26天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
57 1
|
机器学习/深度学习 人工智能 C语言
C语言简单实现14个例题(谭浩强第四版)
版权声明:转载请注明出处:http://blog.csdn.net/dajitui2024 https://blog.csdn.net/dajitui2024/article/details/79396241 1、仅供学习交流参考。
1166 0
|
24天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
48 10
|
24天前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
43 9