链表排序:冒泡和插入

本文介绍了链表排序中两种常见方法:冒泡排序和插入排序。首先,定义了用于存储排序数据的结构体,并通过尾插法生成链表。接着,详细阐述了冒泡排序的工作原理,包括其最好和最坏的时间复杂度。然后,通过代码示例展示了冒泡排序的过程。此外,还解释了插入排序的思路,同样给出了代码实现,说明其平均时间复杂度为O(n^2)。

1.首先定义一个结构体,用于存储排序的数据

typedef struct num
{
    int num;
    struct num *next;
}NUM;

2.生成链表,这里采用的是尾插法


    NUM *p=NULL,*pr=head;
    int num[] = {-10,5,1,10,7,2,90,1,12,45,52,80,-4,2,99};
    int i;
    for(i=0;i<15;i++)
    {                                                                                                                                                                                                                                                                                                                                                                                         
        p=(NUM *)malloc(sizeof(NUM));
        if(head == NULL)
            pr = head = p;
        else
        {
            while(pr->next != NULL)
                pr=pr->next;
            pr->next=p;
        }
        p->num = num[i];
        p->next=NULL;
    }
    return head;
}

3.这里先介绍冒泡排序。冒泡排序的原理:1。比较相邻的两个元素,如果第一个比第二个大就对它进行交换,否则就继续往下执行。这样执行完第一轮后链表中最大的数就在链表的尾端。然后再对未排序的数进行相同的操作。
由此可见冒泡排序最好的时间复杂度是O(n),即一次循环就排好了。最差的时间复杂度是O(n2),要循环(n-1)次才排好序。下面以代码为例

NUM *sort(NUM *head)
{
    NUM *s=head,*pre=head;
    NUM *p=pre->next;
    NUM *temp1=NULL; 
    int i=0,a;
//  先计算出有多少个节点 
    while(s!=NULL)
    {
        s=s->next;
        i++;
    }

    for(a=0; a<i; a++)
    {
        show(head);
        pre=head;
        p=head->next;
        temp1=NULL;
        while(p!= NULL)
        {

            if(pre->num < p->num)
            {
                pre->next=p->next;
                p->next=pre;
                if(temp1!= NULL) 
                    temp1->next=p; 
                else
                    head=p;
            }
            temp1=pre;
            pre=p;
            p=p->next;
        }
    }
    return head;
}

4.插入排序,原理:假设有一个已经排好的序列,要求在这个序列中插入要排的数据,使之还是有序的序列,以代码为例:

struct num *head1=NULL,*p=head,*pr,*p1,*p2;
     while(p!=NULL)
     {
        if(head1==NULL)
        {
            head1=p;
            pr=p->next;
            p=p->next;
            head1->next=NULL;
         }
         else
         {
            if(p->num<=head1->num)
            {
                pr=p->next;
                p->next=head1;
                head1=p;
                p=pr;
             }else if(p->num>head1->num)
             {
                p1=head1;
                while(p1!=NULL)
                {
                   if(p1->next!=NULL)
                   {
                        if(p1->num<p->num && p->num<p1->next->num)
                        {
                            pr=p->next;
                            p2=p1->next;
                            p->next=p2;
                            p1->next=p;
                            p=pr;
                            break;
                        }
                   }
                    else
                     {
                        pr=p->next;
                        p1->next=p;
                        p->next=NULL;
                        p=pr;
                        break; 
                     }
                     p1=p1->next;
                 }
             }
         }
     }
     return head1;

平均来说,插入算法的时间复杂度是O(n2)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值