单链表有多种排序的方法,今天先来说下用选择排序给一个单链表排序。
先来复习下什么是选择排序吧。选择排序,第一次用第一个值与其他值比较,找到最大的交换;第二次循环到第二个值,以此类推到最后一个值,此时,就已经有序。
int main() { int temp,k; int i,j; int a[5]={1,2,3,4,5}; for(i=0;i<5;i++) //外层循环用来改变第一个比较的值 { k=i; //k表示当前最大值的下标 for(j=i+1;j<5;j++) //内层循环用来比较第一个值和剩下的其他值 { if(a[i]<a[j]) k=j; //如果找到大的,记录下标 } temp=a[k]; //交换当前比较的第一个值和最大值 a[k]=a[i]; a[i]=temp; } for(i=0;i<5;i++) { printf("%d",a[i]); } }
其实单链表的排序也和这个差不多,只不过需要记录找到最值的前面一个结点信息,好了,直接看代码吧。
1 struct list *sort(struct list *head) 2 { 3 struct list *p; 4 struct list *phead=NULL; //phead为新的有序链表表头 5 struct list *q; 6 struct list *tail; //tail表示有序链表表尾 7 struct list *p_min; 8 while(head!=NULL) //最外层的循环条件为无序链表不为空 9 { 10 for(p=head,q=head;q->next!=NULL;q=q->next) //p即为快速排序法中的第一个值,用q->next来循环链表寻找最小的值 11 { 12 if(q->next->data<p->data) //寻找最小值 13 { 14 p_min=q; //如果找到,用p_min记录它的前一个结点,q->next的前一个结点为q 15 p=q->next; //用p记录最小的结点 16 } 17 } 18 if(phead==NULL) //如果有序链表为空的话,将最小的结点插入表头 19 { 20 phead=p; 21 tail=p; //表尾也为最小结点 22 } 23 else //如果不为空 24 { 25 tail->next=p; //表尾指向最小的结点 26 tail=p; //新的结点变为表尾 27 } 28 if(p==head) //如果找的的最小结点为无序链表的表头 29 { 30 head=head->next; //将表头直接指向下一个结点 31 } 32 else 33 { 34 p_min->next=p->next; //否则在原链表中删掉最小的结点(此时就用到了最小结点的前驱) 35 } 36 } 37 if(phead!=NULL) //有序链表创建完成之后,将其表尾指向为NULL 38 { 39 tail->next=NULL; 40 } 41 42 return phead; 43 }