Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26417
  • 博文数量: 41
  • 博客积分: 185
  • 博客等级: 入伍新兵
  • 技术积分: 260
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-20 13:48
文章分类

全部博文(41)

文章存档

2013年(20)

2012年(21)

我的朋友
最近访客

分类: C/C++

2013-01-06 22:43:39


点击(此处)折叠或打开

  1. /*带头结点的单向链表操作*/
  2. /*核心:pre=head(pre为前驱结点)*/
  3. /*为方便,结构体只定义一个数据*/
  4. #include"stdio.h"
  5. #include"stdlib.h"
  6. typedef struct Student
  7. {
  8.     int num;
  9.     struct Student *next;
  10. }Stu;


  11. //建立链表
  12. Stu *Creat()
  13. {
  14.     Stu *pre,*p,*head; //pre为p的前驱结点
  15.     pre=head=(Stu *)malloc(sizeof(Stu)); //建立头结点
  16.     head->next=NULL; //不要忘记将头结点指针域置空
  17.     p=(Stu *)malloc(sizeof(Stu)); //建立第一个结点
  18.     scanf("%d",&p->num);
  19.     while(p->num!=0) //输入0,链表建立结束
  20.     {
  21.         pre->next=p;
  22.         pre=p;
  23.         p=(Stu *)malloc(sizeof(Stu));
  24.         scanf("%d",&p->num);
  25.     }
  26.     pre->next=NULL; //pre已指向链尾
  27.     return head;
  28. }


  29. //遍历链表
  30. void Output(Stu *head)
  31. {
  32.     Stu *p;
  33.     p=head->next;
  34.     printf("list:\n");
  35.     while(p!=NULL)
  36.     {
  37.         printf("%d\n",p->num);
  38.         p=p->next;
  39.     }
  40. }


  41. //删除结点
  42. /*需考虑到链表中有多个结点含有待删键值*/
  43. Stu *Delete(Stu *head,int num)
  44. {
  45.     Stu *pre,*p;
  46.     int sign=0; //找到被删结点的标志,0表示未找到,1表示找到
  47.     pre=head; //p的前驱结点
  48.     p=head->next;
  49.     while(p!=NULL) //遍历链表,找到则删之
  50.     {
  51.         if(p->num==num)
  52.         {
  53.             sign=1;
  54.             pre->next=p->next; //删除结点
  55.             free(p); //别释放错了,把pre释放了
  56.         }
  57.         else //*** 关键之处 ***
  58.             pre=p;
  59.         p=pre->next; //考虑到链表中有多个结点含有待删键值,所以不管有没有找到,p始终下移至空。
  60.     }
  61.     if(sign==0) //未找到待删结点
  62.         printf("%d is not in the list!\n");
  63.     return head;
  64. }


  65. //插入结点1(原链表已排序)
  66. /*<不要考虑插入到链尾>*/
  67. Stu *Insert(Stu *head,int num)
  68. {
  69.     Stu *pre,*p,*New_code;
  70.     pre=head;
  71.     p=head->next;
  72.     New_code=(Stu *)malloc(sizeof(Stu)); //开辟一个内存存放新结点
  73.     New_code->num=num;
  74.     while(p!=NULL&&p->num<New_code->num)
  75.     {
  76.         pre=p;
  77.         p=pre->next; //等价于p=p->next;
  78.     }
  79.     pre->next=New_code;
  80.     New_code->next=p;
  81.     return head;
  82. }
  83. /*注意:
  84. 在while(p!=NULL&&p->num!=num) 中,p!=NULL与p->num!=num的顺序不能颠倒。
  85. 如果写成:while(p->num!=num&&p!=NULL),将导致程序崩溃。
  86. 因为程序从左至右进行运算,先进行p->num运算,再进行p!=NULL运算。当p==NULL时,
  87. p->num运算会泄漏内存,引起程序崩溃!
  88. */



  89. //插入结点2(原链表已排序)
  90. /*<需要考虑插入到链尾>*/
  91. Stu *Insert_2(Stu *head,int num)
  92. {
  93.     Stu *pre,*p,*New_code;
  94.     pre=head;
  95.     p=head->next;
  96.     New_code=(Stu *)malloc(sizeof(Stu)); //开辟一个内存存放新结点
  97.     New_code->num=num;
  98.     while(New_code->num>p->num&&p->next!=NULL)
  99.     {
  100.         pre=p;
  101.         p=p->next;
  102.     }
  103.     if(New_code->num<=p->num) //待插入结点不在链尾
  104.     {
  105.         pre->next=New_code;
  106.         New_code->next=p;
  107.     }
  108.     else //待插入结点在链尾
  109.     {
  110.         p->next=New_code;
  111.         New_code->next=NULL;
  112.     }
  113.     return head;
  114. }

  115.     
  116. //统计链表长度
  117. int Length(Stu *head)
  118. {
  119.     Stu *p;
  120.     int i=0;
  121.     p=head->next;
  122.     while(p!=NULL)
  123.     {
  124.         i++;
  125.         p=p->next;
  126.     }
  127.     return i;
  128. }


  129.     
  130. //查找结点<可查找多个结点>
  131. void Search(Stu *head,int num)
  132. {
  133.     Stu *p;
  134.     int sign=0;
  135.     p=head->next;
  136.     while(p!=NULL)
  137.     {
  138.         if(p->num==num)
  139.         {
  140.             sign=1;
  141.             printf("%d has been fond!\n",num);
  142.         }
  143.         p=p->next;
  144.     }
  145.     if(sign==0)
  146.         printf("%d is not in the list!\n",num);
  147. }



  148. //链表选择排序
  149. Stu *Selectsort(Stu *head)
  150. {
  151.     Stu *p,*q,*min;
  152.     int temp;
  153.     for(p=head->next;p!=NULL;p=p->next)
  154.     {
  155.         min=p;
  156.         for(q=p->next;q!=NULL;q=q->next)
  157.             if(q->num<min->num)
  158.                 min=q;
  159.         if(min!=p)
  160.         {
  161.             temp=p->num;
  162.             p->num=min->num;
  163.             min->num=temp;
  164.         }
  165.     }
  166.     return head;
  167. }


  168. //链表逆置
  169. Stu *Reverse(Stu *head)
  170. {
  171.     Stu *pre,*cur,*temp; //cur为当前结点,pre为前驱结点,temp为临时变量,保存前驱结点的地址。
  172.     cur=head->next;
  173.     pre=NULL;
  174.     while(cur->next!=NULL)
  175.     {
  176.         temp=pre;
  177.         pre=cur;
  178.         cur=cur->next;
  179.         pre->next=temp;
  180.     }
  181.     cur->next=pre;
  182.     head->next=cur; //不懂就画个图,一步一步推。
  183.     return head;
  184. }

  185. /*这样也可*/
  186. //链表逆置
  187. Stu *Reverse_2(Stu *head)
  188. {
  189.     Stu *pre,*cur,*temp; //cur为当前结点,pre为前驱结点,temp为临时变量,保存前驱结点的地址。
  190.     cur=head->next;
  191.     pre=NULL;
  192.     while(cur!=NULL)
  193.     {
  194.         temp=pre;
  195.         pre=cur;
  196.         cur=cur->next;
  197.         pre->next=temp;
  198.     }
  199.     head->next=pre; //不懂就画个图,一步一步推。
  200.     return head;
  201. }


  202. void main()
  203. {
  204.     int Length(Stu *head);
  205.     void Output(Stu *head);
  206.     void Search(Stu *head,int num);
  207.     Stu *Creat();
  208.     Stu *Delete(Stu *head,int num);
  209.     Stu *Insert(Stu *head,int num);
  210.     Stu *Selectsort(Stu *head);
  211.     Stu *Reverse(Stu *head);
  212.     Stu *head;
  213.     int del_num,insert_num,search_num,length;
  214.     printf("input data:\n");
  215.     head=Creat();
  216.     printf("The original ");
  217.     Output(head);
  218.     head=Selectsort(head);
  219.     printf("The sorted ");
  220.     Output(head);
  221.     length=Length(head);
  222.     printf("The length of the list is:%d\n",length);
  223.     printf("input the number you want to search:");
  224.     scanf("%d",&search_num);
  225.     Search(head,search_num);
  226.     printf("input the number you want to delete:");
  227.     scanf("%d",&del_num);
  228.     head=Delete(head,del_num);
  229.     Output(head);
  230.     printf("input the number you want to insert:");
  231.     scanf("%d",&insert_num);
  232.     head=Insert(head,insert_num);
  233.     Output(head);
  234.     head=Reverse(head); //不能在插入之前逆置,若逆置,将改变原来的排序方向,导致结果错误。
  235.     printf("The reversed ");
  236.     Output(head);
  237. }

阅读(410) | 评论(0) | 转发(0) |
0

上一篇:链表逆序

下一篇:折半查找法

给主人留下些什么吧!~~