排序

一、冒泡排序

1.思想:两两比较相邻记录的关键字,如果反序就 交换,直到没有反序为止

2.代码一

从小到大排序

从最后一个数开始两两比较,将较小的数字放在前面,第一轮比较过后第一个数字为最小值。

在后面的比较中就不用在比较第一个数字了j<=i

void BubbleSort(SqList *L)

{    

    int i,j;

    for(i=1;i<L->length;i++)

        {

            for(j=L->length-1;j>=i;j--)   //j从后往前循环

                {if(L->r[j]>L->r[j+1])

                    swap(L.j,j+1)

                }

        }

}

代码二:冒泡排序优化 

设置一个标记变量flag,当序列已经有序时,不需要进行后面的循环

void BubbleSort2(SqList *L)

{

    int ,i,j;

    Status flag=TRUE;

    for(i=1;i<L->length&&flag;i++)

        {

            flag=FALSE;

            for (j=L->length-1;j>=i;j--)

                if(L->r[j]>L->r[j+1]])

                    {swap(L,j,j+1);

                     flag=TRUE;

                    }

        }

}

3.复杂度

最后改进的代码,可以推断出当序列有序时,需要n-1次比较,没有数据交换,时间复杂度为O(n)

最坏的情况,当为逆序时,需要1+2+3……+(n-1)=n(n-1)/2

总的时间复杂度是O(n²)

二、简单选择排序

1.通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个记录交换

2.代码

void  SelectSort(SqList *L) 

{

    int i,j,min;

    for(i=1;i<L->lengthli++)

    {

        min=i;  //将当前下标定义为最小值下标

        for(j=L->length;j>=i;j--)

        {

            if(L->r[min]>L->r[j])

                min=j;

        }

        if (min!=i)         //若min不等于i,说明找到最小值,交换

           swap(L,i,min);

    }

}

时间复杂度O(n²),但略优于冒泡排序

三、直接插入排序

1.基本思路:将一个记录插入到已经排序好的有序列表中,从而得到一个新的、记录数增加一的有序表

第一步:i=2假设第一个数已经放好

第二步:比较第i个数与第i-1个数的大小,如果第i个数<第i-1个数

        ①将第i个数赋给r[0],设置哨兵

        ②比较第i个数(r[0])与前面几个数的大小关系,将记录后移

        ③插入到正确位置

2.代码

void DirectSort(SqList *L)

{

    int i,j;

    for(i=2;i<L->length;i++)

     {

           if(L->r[i]<L->r[i-1])

            {

                L->r[0]=L->r[i];

                for(j=i-1;r[j]>r[0];j--)

                    L->r[j+1]=L->r[j];

                L->r[j+1]=l->r[0];

            }

    }

}

3.复杂度

平均比较和移动次数为n²/4,时间复杂度O(n²),比冒泡排序和简单选择排序性能好

四、希尔排序

1.基本有序:小的关键字基本在前面,打得关键字基本在后面

2.思路:将相隔某个增量的记录组成一个子序列,实现跳跃式移动

五、快速排序

1.基本思想:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分小,之后分别对这两个部分记录继续排序,以达到整个序列有序的目的。

步骤:①选定pivotkey,将记录分成两部分,其中一部分比pivotkey大,一部分比他小   

②:对子表递归排序

2.代码 

void QuickSort(SqList *L)

{

    QSort(L,1,L->length);

}

void QSort(SqList *L,int low ,int high)

{

    int pivot;

    if (low<high)

`    {

        pivot=Partition(L,low,high);

        QSort(L,low,pivot-1);//对低子表递归排序

        QSort(L,pivot+1,high); //对高子表递归排序

    }

}

void Partition(SqList*L, int low,int high)

{

    int pivotkey=L->r[low];//用表的第一个记录做pivotkey

    while(low<high)

  {    

       if(low<high&&L->r[high]>=pivotkey)

            high--;

        swap(L,low,high):

        if(low<high&&L->r[low]<=pivoykey)

            low++;

        swap(L,low,high);

    }

    return low;  //返回pivot所在的位置

}    

3.复杂度分析

在最优的情况下,时间复杂度为O(nlogn)(也是平均复杂度)

最坏的情况,如果待排序的序列为正序或者逆序,时间复杂度为O(n²)

4.改进方法

可以取中间的数赋值给pivotkey

六、归并排序


        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值