单链表有多种排序的方法,今天先来说下用选择排序给一个单链表排序。

先来复习下什么是选择排序吧。选择排序,第一次用第一个值与其他值比较,找到最大的交换;第二次循环到第二个值,以此类推到最后一个值,此时,就已经有序。

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 }