Chinaunix首页 | 论坛 | 博客
  • 博客访问: 464086
  • 博文数量: 68
  • 博客积分: 2606
  • 博客等级: 上尉
  • 技术积分: 1308
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-13 23:01
文章分类
文章存档

2012年(6)

2011年(62)

分类: C/C++

2011-08-24 15:37:02

------------------------------------------
本文为本人原创,欢迎转载!
转载请注明出处:snowboy.blog.chinaunix.net
雪夜流星
------------------------------------------
双链表在笔试面试中也是常用考点,下面为双链表的一些基本操作,附带测试程序main,可在linux下通过gcc编译直接运行。
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. /*定义数据结构类型*/
  4. typedef struct dnode
  5. {
  6.     int data;
  7.     struct dnode *pre;/*前驱*/
  8.     struct dnode *next;/*后继*/
  9. } dlink;

  10. /*****************************************************************
  11.  *功能描述:创建一个带头结点的双链表,头结点数据域不存放有效数据
  12.  *传入参数:无
  13.  *传出参数:无
  14.  *返回值: 创建后的双链表的头指针
  15.  ****************************************************************/
  16. dlink *creat()
  17. {
  18.     dlink *head = NULL;
  19.     dlink *p = NULL;
  20.     dlink *s = NULL;
  21.     int d;
  22.     
  23.     /*为头结点分配空间*/
  24.     head = (dlink *)malloc(sizeof(dlink));
  25.     if(!head)
  26.     {
  27.         printf("error\n");
  28.         exit(1);
  29.     }
  30.     
  31.     p = head;
  32.     while(1)
  33.     {
  34.         printf("please input data:");
  35.         scanf("%d", &d);
  36.         if(d <= 0)
  37.         {
  38.             break;/*当输入数据小于0时退出循环*/
  39.         }
  40.         s = (dlink *)malloc(sizeof(dlink));
  41.         if(!s)
  42.         {
  43.             printf("error\n");
  44.             exit(1);
  45.         }
  46.         s->data = d;
  47.         
  48.         /*将新增结点插入到链表尾部,并更新当前指针的指向*/
  49.         p->next = s;
  50.         s->pre = p;
  51.         p = s;
  52.     }

  53.     p->next = NULL;/*将最后一个结点的后继赋空*/
  54.     head->pre = NULL;/*将第一个结点的前驱赋空*/
  55.     
  56.     printf("create double list success\n");
  57.     return head;
  58. }

  59. /*****************************************************************
  60.  *功能描述:删除双链表中的一个结点
  61.  *传入参数:head:双链表的头指针 num:需删除结点的数据域
  62.  *传出参数:无
  63.  *返回值: 删除结点后的双链表的头指针
  64.  ****************************************************************/
  65. dlink *del(dlink *head, int num)
  66. {
  67.     dlink *p = NULL;
  68.     
  69.     /*判断链表是否为空 */
  70.     if(!head || !head->next)
  71.     {
  72.         printf("no data del\n");
  73.         return NULL;
  74.     }
  75.     
  76.     /*文中链表为带头结点的,从头结点的下一个结点开始*/
  77.     p = head->next;
  78.     
  79.     /*如果num==p->data或者p->next为空即到了链表尾部则退出循环,通过此while循环找到需要删除的数据*/
  80.     while((num!=p->data) && p->next)
  81.     {
  82.         p = p->next;
  83.     }
  84.     if(num == p->data)
  85.     {    
  86.         if(!p->next)/*删除结点为尾结点*/
  87.         {
  88.             p->pre->next = NULL;
  89.             free(p);
  90.             printf("del tail\n");
  91.         }
  92.         else/*从前面代码可知删除的结点不可能为头结点,所以可以将其他情况归为一类*/
  93.         {
  94.             p->pre->next = p->next;
  95.             p->next->pre = p->pre;
  96.         
  97.             free(p);
  98.         }
  99.     }
  100.     else/*未找到要删除的结点*/
  101.     {
  102.         printf("couldn't been deleted the data:%d\n", num);
  103.         return NULL;
  104.     }
  105.     
  106.     printf("delete node success\n");

  107.     return head;
  108. }

  109. /*****************************************************************
  110.  *功能描述:插入一个新结点到双链表中
  111.  *传入参数:head:双链表的头指针 num:需删除结点的数据域
  112.  *传出参数:无
  113.  *返回值: 插入结点后的双链表的头指针
  114.  ****************************************************************/
  115. dlink *insert(dlink *head, int num)
  116. {
  117.     dlink *p = NULL;
  118.     dlink *p0 = NULL;
  119.     
  120.     /*判空*/
  121.     if(!head || !head->next)
  122.     {
  123.         return NULL;
  124.     }
  125.     
  126.     /*分配空间*/
  127.     p0 = (dlink *)malloc(sizeof(dlink));
  128.     if(!p0)
  129.     {
  130.         printf("malloc error\n");
  131.         exit(1);
  132.     }
  133.     p0->data = num;
  134.     p = head->next;
  135.     
  136.     /*确定插入位置*/
  137.     while(p->next && (p0->data>p->data))
  138.     {
  139.         p = p->next;
  140.     }
  141.     if(p0->data <= p->data)
  142.     {
  143.         p->pre->next = p0;
  144.         p0->pre = p->pre;
  145.         p0->next = p;
  146.         p->pre = p0;        
  147.     }
  148.     else/*比任何数都大,直接插到链表尾部*/
  149.     {
  150.         p->next = p0;
  151.         p0->pre = p;
  152.         p0->next = NULL;
  153.     }

  154.     printf("insert success\n");    
  155.     
  156.     return head;
  157. }

  158. /*****************************************************************
  159.  *功能描述:打印一个带头结点的双链表中存放的数据(不包含头结点)
  160.  *传入参数:无
  161.  *传出参数:无
  162.  *返回值: 无
  163.  ****************************************************************/
  164. void printl(dlink *head)
  165. {
  166.     dlink *p = NULL;
  167.     
  168.     if(!head || !head->next)
  169.     {
  170.         return;
  171.     }
  172.     p = head->next;
  173.     while(p)
  174.     {
  175.         printf("%d ", p->data);
  176.         p = p->next;
  177.     }
  178.     printf("\n");
  179.         
  180.     return;
  181. }

  182. int main(void)
  183. {
  184.     dlink *p = NULL;
  185.     dlink *head = NULL;
  186.     int d;
  187.     
  188.     head = creat();
  189.     printl(head);
  190.     
  191.     printf("please input insert data:");
  192.     scanf("%d", &d);
  193.     p = insert(head, d);
  194.     printl(p);
  195.     
  196.     
  197.     printf("please input del data:");
  198.     scanf("%d", &d);
  199.     p = del(head, d);
  200.     printl(p);
  201.     
  202.     
  203.     return 0;
  204. }
阅读(2308) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~