免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3516 | 回复: 5
打印 上一主题 下一主题

[C] 单向链表数据插入销毁问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-09-29 16:12 |只看该作者 |倒序浏览
各位大牛们好,请问在一个已创建的单向链表中插入一个新数据后再执行销毁链表操作没有将这个新插入的结点删除,是否有什么好办法?
代码如下:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #define stLen        sizeof(stNode)

  4. typedef struct student
  5. {
  6.         char        sname[10];
  7.         int                iage;
  8.         struct student        *next;
  9. }stNode;

  10. //创建一个定长的单向链表
  11. stNode *create(int num)
  12. {
  13.         stNode *p,*q,*head;
  14.         int icount = 0;

  15.         p = q = (stNode *)malloc(stLen);
  16.        
  17.         head = NULL;

  18.         while(num--)
  19.         {
  20.                 icount++;

  21.                 p = (stNode *)malloc(stLen);
  22.                 scanf("%s%d",&p->sname,&p->iage);

  23.                 if(icount == 1)        head = p;
  24.                 else q->next = p;
  25.                 p->next = NULL;
  26.                 q = p;
  27.         }

  28.         q->next = NULL;

  29.         return head;
  30. }

  31. //链表数据打印输出
  32. void myprint(stNode *node)
  33. {
  34.         if(node == NULL)
  35.         {
  36.                 printf("输入的链表为空,链表不能为空!\n");
  37.                 exit (-1);
  38.         }

  39.         while(node)
  40.         {
  41.                 printf("name->[%s],age->[%d]\n",node->sname,node->iage);
  42.                 node = node->next;
  43.         }
  44. }

  45. //计算链表长度
  46. int Node_Length(stNode *node)
  47. {
  48.         int iLength = 0;
  49.         while(node){
  50.                 node = node->next;
  51.                 iLength++;
  52.         }
  53.         return iLength;
  54. }

  55. //删除指定位置记录
  56. stNode *Node_Delete(stNode *node,int inum)
  57. {
  58.         stNode *p1,*p2;
  59.         int node_length = 0,iRun = 0;

  60.         if(node == NULL)
  61.         {
  62.                 printf("输入的链表为空,链表不能为空!\n");
  63.                 exit (-1);
  64.         }

  65.         p1 =  node;
  66.         node_length = Node_Length(node);

  67.         if(node_length < inum)
  68.         {
  69.                 printf("输入的链表长度[%d]不足[%d]\n",node_length,inum);
  70.                 exit (-1);
  71.         }

  72.         while(iRun++ < (inum-1))
  73.         {
  74.                 p2 = p1;
  75.                 p1 = p1->next;
  76.         }

  77.         if(p1 == node)
  78.         {
  79.                 if(node_length == 1)
  80.                 {
  81.                         free(node);
  82.                         node = NULL;
  83.                 }
  84.                 else node = p1->next;
  85.                 free(p1);
  86.         }

  87.         else p2->next = p1->next;

  88.         return node;
  89. }

  90. //插入新数据到链表指定位置
  91. stNode *Node_Insert(stNode *node,stNode *innode,int inum)
  92. {
  93.         stNode *p1,*p2;
  94.         int node_length = 0,iRun = 0;

  95.         node_length = Node_Length(node);

  96.         if(node == NULL || inum > node_length || innode == NULL)
  97.         {
  98.                 printf("链表为空或需插入的位置[%d]超过链表长度[%d]!\n",inum,node_length);
  99.                 exit(-1);
  100.         }

  101.         p1 = node;

  102.         while(iRun++ < inum)
  103.         {
  104.                 p2 = p1;
  105.                 p1 = p1->next;
  106.         }

  107.         p2->next = innode;
  108.         p2->next->next = p1;

  109.         return node;
  110. }

  111. //更新链表数据
  112. stNode *Node_Update(stNode *node,stNode *upnode,int inum)
  113. {
  114.         stNode *p1;
  115.         int node_length = 0,iRun = 0;

  116.         node_length = Node_Length(node);

  117.         if(node == NULL || inum > node_length || upnode == NULL)
  118.         {
  119.                 printf("链表为空或需插入的位置[%d]超过链表长度[%d]!\n",inum,node_length);
  120.                 exit(-1);
  121.         }

  122.         p1 = node;

  123.         while(iRun++ < inum-1)
  124.         {
  125.                 p1 = p1->next;
  126.         }

  127.         strcpy(p1->sname,upnode->sname);
  128.         p1->iage = upnode->iage;

  129.         return node;
  130. }

  131. //链表逆序
  132. stNode *Node_Reverse(stNode *node)
  133. {
  134.         stNode *next,*prev;

  135.         prev = NULL;

  136.         while(node)
  137.         {
  138.                 next = node->next;
  139.                 node->next = prev;
  140.                 prev = node;
  141.                 node = next;
  142.         }

  143.         return prev;
  144. }

  145. //递归算法逆序链表
  146. stNode *Node_Reverse2(stNode *node)
  147. {
  148.         stNode        *NewHead;

  149.         if(node == NULL || node->next == NULL)
  150.                 return node;

  151.         NewHead = Node_Reverse2(node->next);

  152.         node->next->next = node;
  153.         node->next = NULL;

  154.         return NewHead;
  155. }

  156. //销毁链表
  157. stNode *Node_Destroy(stNode *node)
  158. {
  159.         stNode *pnode;

  160.         while(node)
  161.         {
  162.                 pnode = node->next;
  163.                 free(node);
  164.                 node = pnode;
  165.         }

  166.         return node;
  167. }

  168. int main()
  169. {
  170.         stNode *p,*q,*pn1,*pn2;
  171.         int iLength = 0;
  172.         int        iDelete = 0;
  173.         int        iInsert = 0;
  174.         int        iUpdate = 0;
  175.        
  176.         printf("开始创建链表\n");
  177.         printf("输入需要创建链表的大小:");
  178.         scanf("%d",&iLength);

  179.         p = create(iLength);
  180.         myprint(p);

  181.         printf("输入需要删除的链表位置:");
  182.         scanf("%d",&iDelete);

  183.         Node_Delete(p,iDelete);
  184.         myprint(p);

  185.         q = (stNode *)malloc(stLen);
  186.         printf("输入需要插入的位置和姓名年龄:\n");
  187.         scanf("%d%s%d",&iInsert,&q->sname,&q->iage);

  188.         Node_Insert(p,q,iInsert);
  189.         myprint(p);

  190.         pn1 = (stNode *)malloc(stLen);
  191.         printf("输入需要修订的链表位置和姓名年龄:\n");
  192.         scanf("%d%s%d",&iUpdate,&pn1->sname,&pn1->iage);

  193.         Node_Update(p,pn1,iUpdate);
  194.         myprint(p);

  195.         printf("现在开始逆序输出链表:\n");
  196.         //pn2 = Node_Reverse(p);
  197.         pn2 = Node_Reverse2(p);
  198.         myprint(pn2);

  199.         printf("开始销毁链表:\n");
  200.         Node_Destroy(pn2);
  201.         myprint(pn2);

  202.         free(p);
  203.         free(q);
  204.         free(pn1);
  205.         free(pn2);

  206.         return 0;
  207. }
复制代码

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
2 [报告]
发表于 2014-09-29 17:01 |只看该作者
没有看懂你的问题

论坛徽章:
7
天秤座
日期:2014-08-07 13:56:30丑牛
日期:2014-08-27 20:34:21双鱼座
日期:2014-08-27 22:02:21天秤座
日期:2014-08-30 10:39:11双鱼座
日期:2014-09-21 20:07:532015年亚洲杯之日本
日期:2015-02-06 14:00:282015亚冠之大阪钢巴
日期:2015-11-02 14:50:19
3 [报告]
发表于 2014-09-29 17:29 |只看该作者
貌似有个值传递的问题,destroy没有把NULL返回给pn2,所以你的pn2还是非空,print出来还是有表在。

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
4 [报告]
发表于 2014-09-30 17:06 |只看该作者
没有表头结构体的链表都得用二维指针来插入或者删除吧!否则,就没有下文了(直接coredump)。

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
5 [报告]
发表于 2014-09-30 17:43 |只看该作者
我的版本。仅供参考。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. typedef struct student
  5. {
  6.         char sname[10];
  7.         int iage;
  8.         struct student *next;
  9. }stNode;

  10. int Node_Delete(stNode **io_tab, int inum)
  11. {
  12.         stNode **node, *temp;

  13.         if (io_tab != NULL && inum >= 0) {
  14.                 node = io_tab;
  15.                 while (*node != NULL) {
  16.                         if (inum == 0) {
  17.                                 temp = *node;
  18.                                 *node = (*node)->next;
  19.                                 free(temp);
  20.                                 return 0;
  21.                         }
  22.                         node = &(*node)->next;
  23.                         --inum;
  24.                 }
  25.         }
  26.         return -1;
  27. }

  28. int Node_Insert(stNode **io_tab, const char sname[10], int iage, stNode **o_node)
  29. {
  30.         stNode *node, *temp;

  31.         if (io_tab != NULL && sname != NULL) {
  32.                 /* get the last node */
  33.                 node = *io_tab;
  34.                 if (node != NULL) {
  35.                         while (node->next != NULL) {
  36.                                 node = node->next;
  37.                         }
  38.                 }
  39.                 /* append a new node */
  40.                 temp = (stNode *)malloc(sizeof(stNode));
  41.                 if (temp != NULL) {
  42.                         memset(temp, 0, sizeof(stNode));
  43.                         strncpy(temp->sname, sname, 10);
  44.                         temp->iage = iage;
  45.                         if (node == NULL) {
  46.                                 *io_tab = temp;
  47.                         }else {
  48.                                 node->next = temp;
  49.                         }
  50.                         if (o_node != NULL) {
  51.                                 *o_node = temp;
  52.                         }
  53.                         return 0;
  54.                 }
  55.         }
  56.         return -1;
  57. }

  58. int Node_Update(stNode *tab, int inum, const char sname[10], int iage)
  59. {
  60.         if (tab != NULL && inum >= 0 && sname != NULL) {
  61.                 while (tab != NULL) {
  62.                         if (inum == 0) {
  63.                                 strncpy(tab->sname, sname, 10);
  64.                                 tab->iage = iage;
  65.                                 return 0;
  66.                         }
  67.                         tab = tab->next;
  68.                         --inum;
  69.                 }
  70.         }
  71.         return -1;
  72. }

  73. int Node_Destroy(stNode **io_tab)
  74. {
  75.         stNode *node, *temp;

  76.         if (io_tab != NULL) {
  77.                 node = *io_tab;
  78.                 while (node != NULL) {
  79.                         temp = node;
  80.                         node = node->next;
  81.                         free(temp);
  82.                 }
  83.                 *io_tab = NULL;
  84.                 return 0;
  85.         }
  86.         return -1;
  87. }

  88. int Node_Reverse(stNode **io_tab)
  89. {
  90.         stNode *tab, *node, *temp;

  91.         if (io_tab != NULL) {
  92.                 tab = NULL;
  93.                 node = *io_tab;
  94.                 while (node != NULL) {
  95.                         temp = node;
  96.                         node = node->next;
  97.                         temp->next = tab;
  98.                         tab = temp;
  99.                 }
  100.                 *io_tab = tab;
  101.                 return 0;
  102.         }
  103.         return -1;
  104. }

  105. int myprint(stNode *tab)
  106. {
  107.         int cnt;

  108.         cnt = 0;
  109.         while(tab != NULL) {
  110.                 printf("%d: name->[%.*s],age->[%d]\n", cnt, 10, tab->sname, tab->iage);
  111.                 tab = tab->next;
  112.                 ++cnt;
  113.         }
  114.         return 0;
  115. }

  116. int main(void)
  117. {
  118.         char sname[10];
  119.         int iage;
  120.         stNode *tab;
  121.         int iLength = 0;
  122.         int iDelete = 0;
  123.         int iInsert = 0;
  124.         int iUpdate = 0;

  125.         tab = NULL;

  126.         printf("开始创建链表\n");
  127.         printf("输入需要创建链表的大小: ");
  128.         scanf("%d", &iLength);
  129.         while (iLength-- > 0) {
  130.                 Node_Insert(&tab, "<null>", iLength, NULL);
  131.         }
  132.         myprint(tab);

  133.         printf("输入需要删除的链表位置: ");
  134.         scanf("%d", &iDelete);
  135.         Node_Delete(&tab, iDelete);
  136.         myprint(tab);

  137.         printf("输入需要插入的姓名和年龄:\n");
  138.         scanf("%s%d", sname, &iage);
  139.         Node_Insert(&tab, sname, iage, NULL);
  140.         myprint(tab);

  141.         printf("输入需要修订的链表位置和姓名年龄:\n");
  142.         scanf("%d%s%d", &iUpdate, sname, &iage);
  143.         Node_Update(tab, iUpdate, sname, iage);
  144.         myprint(tab);

  145.         printf("现在开始逆序输出链表:\n");
  146.         Node_Reverse(&tab);
  147.         myprint(tab);

  148.         printf("开始销毁链表:\n");
  149.         Node_Destroy(&tab);
  150.         myprint(tab);
  151.        
  152.         return 0;
  153. }
复制代码

论坛徽章:
0
6 [报告]
发表于 2014-10-09 10:32 |只看该作者
回复 5# cobras
前段时间比较忙,没来得及回复,不好意思,多谢帮助,等下去试试你的方法


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP