链表的排序

排序的基本思路:

1、找到链表中最小的节点a;

2、将a连接到新链表上;

3、将a从原链表中删除;

4、回到1,反复执行至原链表节点数为0;

代码如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define LEN sizeof(struct Numlist)
  4 
  5 //定义链表节点
  6 struct Numlist
  7 {    
  8     int num;//数据域
  9     
 10     int id;//定义节点ID
 11 
 12     struct Numlist * next;//指针域
 13 };
 14 //定义全局计数变量n
 15 int n=1;
 16 
 17 //创建链表的函数
 18 struct Numlist * creatList()
 19 {
 20     //头指针
 21     struct Numlist * head;
 22     //龙套指针、新建指引指针
 23     struct Numlist * pTax,* pNew;
 24     //开始创建
 25     printf("输入数据,每输入一个数据按一次回车,当输入“59438”时,表示终止输入,\n且“59438”不计入数据组。\n");    
 26     //创建第一个节点
 27     head=pTax=(struct Numlist *)malloc(LEN);
 28     //定义输入变量
 29     int val;
 30     while(val!=59438)
 31     {
 32         //输入数据
 33         printf("输入第%d个数据:",n);        
 34         scanf("%d",&val);        
 35         //将Val放入第一个节点的数据域
 36         pTax->num=val;
 37         //为节点赋予ID
 38         pTax->id=n++;
 39         //继续创建节点
 40         pNew=(struct Numlist *)malloc(LEN);
 41         //将新创建的节点的地址赋给上一个节点的指针域
 42         pTax->next=pNew;
 43         //将龙套指针指向新的节点
 44         pTax=pNew;
 45         
 46     }
 47     n=n-2;
 48 
 49     //删除最后一个节点,因为最后一个节点的数据域为“59438”
 50     pTax=head;//将龙套指针拉回头节点
 51     for(int i=0;i<n;i++) pTax=pTax->next;//将龙套指针定位到“倒数第二个节点”
 52     //删除
 53     free(pTax->next);//释放掉最后一个节点
 54     pTax->next=0;    //倒数第二个节点的指针域归0
 55     
 56 
 57     return (head);
 58 }
 59 
 60 //遍历链表的函数
 61 void Traverse(struct Numlist * head)
 62 {
 63     //定义龙套指针
 64     struct Numlist * pTax;
 65     pTax=head;
 66     printf("遍历链表:\n链表长度为%d\n",n);
 67     while(pTax->next!=0)
 68     {
 69         printf(" %d",pTax->num);
 70         pTax=pTax->next;
 71     }
 72     printf("\n\t遍历完成!\n");
 73     
 74 }
 75 
 76 
 77 //为链表排序的函数
 78 //调用此函数之后,原链表被重排,成为一个有序的新链表
 79 //函数返回新链表的头指针
 80 struct Numlist * sort(struct Numlist * head)
 81 {
 82     struct Numlist * pTax;
 83     struct Numlist * newhead,* newpTax;
 84     //为新链表创建一个临时的节点(第一个节点)
 85     newhead=newpTax=(struct Numlist *)malloc(LEN);
 86     newpTax->num=0;    
 87     int n2=n;
 88     for(int j=0;j<n2;j++)
 89     {
 90         //找到当前链表中的最小的节点,并将该节点连接到新链表上去
 91         pTax=head;
 92         int minId=pTax->id;
 93         int minVal=pTax->num;
 94         pTax=pTax->next;
 95         for(int i=0;i<n;i++)
 96         {
 97             if(minVal>pTax->num)
 98             {
 99                 minVal=pTax->num;
100                 minId=pTax->id;
101                 newpTax->next=pTax;
102                 
103             }        
104         }
105 
106         //删掉该节点
107         //拉回去
108         pTax=head;
109         if(minId!=1&&minId!=n2)
110         {
111             for(int i=1;i<minId-1;i++) pTax=pTax->next;
112             pTax->next=(pTax->next)->next;        
113         }else if(minId==1)
114         {
115             pTax=head=pTax->next;        
116         }else if(minId==n2)
117         {
118             for(int i=1;i<minId-1;i++) pTax=pTax->next;
119             pTax->next=0;
120         }
121         //原链表个数减一
122         n--;
123         
124 
125         
126 
127 
128         //新链表准备新链接
129         newpTax=newpTax->next;
130     }
131 
132     //删掉新链表的第一个(临时)节点
133     newpTax=newhead;
134     newhead=newhead->next;
135     free(newpTax);
136 
137     return (newhead);
138 }
139 void main(void)
140 {
141 
142     //定义头指针
143     struct Numlist * head;
144     struct Numlist * newhead;
145     //创建链表    
146     head=creatList();
147     //遍历链表    
148     Traverse(head);
149     //排序链表
150     newhead=sort(head);
151     //遍历排序后的链表
152     printf("\n排序后:\n");
153     Traverse(newhead);
154 
155 }

 

posted @ 2012-09-28 00:01  iFinVer  阅读(469)  评论(0编辑  收藏  举报