• 排序算法学习之交换排序(冒泡排序,快速排序)


    冒泡排序

    名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。


    步骤:

    进行第i趟排序:

    • 比较第1个记录和第2个记录关键字,逆序则交换两个记录
    • 往后比较第2个记录和第3个记录,逆序则交换两个记录
    • 依次往后比较,直到比较完第n-i个记录和第n-i+1个记录,逆序则交换两个记录
    • 关键字最大的记录被交换到第n-i+1的位置

    正序:只进行一趟排序,并且只比较n-1次,无需交换记录

    逆序:n个元素序列共进行n-1趟排序,需进行,共n(n-1)/2次比较

    void BubbleSort(SqList *L)
    {
        int n=L->length;//表长度
        for(int i=1;i<n;i++)//n个元素只进行n-1趟排序
            for(int j=0;j<n-i;j++)//从第0个元素开始和后面的元素比较,直到第n-i和第n-i+1个记录比较完
            {
                if(L->r[j]>L->r[j+1])
                {
                    int key=L->r[j];//交换记录
                    L->r[j]=L->r[j+1];
                    L->r[j+1]=key;
                }
            }
        return;
    }

    冒泡排序时间复杂度为O(n^2)


    快速排序

    快速排序是对冒泡排序的一种改进。

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


    ##此处只能选L->r[low]作为枢值,选其他作为枢值会出现枢值丢失(被覆盖)的情况
    int Partition(SqList *L,int low,int high)
    {
        int temp=L->r[low];//临时变量保存枢轴值
        while(low<high){//当low==high 说明已经找到枢轴位置,可以区分大小左右序列
            while(low<high&&L->r[high]>=temp)  --high;//大于等于枢轴值,则继续从后往前扫描,
            L->r[low]=L->r[high];//将小于枢轴的值赋值给低位
            while(low<high&&L->r[low]<=temp)  low++;//小于等于枢轴值,则继续从前往后扫描
            L->r[high]=L->r[low];//将大于枢轴的值赋值给高位
        }
        int final=low;//枢值最后位置
        L->r[final]=temp;//用临时变量填回
        return final;//返回位置
    }
    void QSort(SqList *L,int low,int high)
    {
        if(low<high){//长度必须大于1,等于1就无需再继续排序
            int index=Partition(L,low,high);//返回枢轴的位置,左边均小于枢轴,右边均大于等于枢轴
            QSort(L,low,index-1);//对枢轴左边序列就进行排序
            QSort(L,index+1,high);//对枢轴右边序列进行排序
        }
        return;
    }
    void QuickSort(SqList *L)//对顺序表L进行快速排序
    {
        QSort(L,0,L->length-1);//记录从0开始,length-1结束
        return;
    }

    时间复杂度

    1. 当序列为正序时,选取第一个记录为枢轴,则左边为空,右边为正序子序列,但是虽然不用赋值,但是比较次数很多,时间复杂度为 O(n^2)
    2. 当序列为为逆序时,此时快速排序类似于low和high记录前后交换,并且low++,high--,颠倒逆序为正序
    3. 当序列数据随机分布时,以第一个关键字为基准分为两个子序列,两个子序列的元素个数接近相等,此时执行效率最好。

    数据越随机分布时,快速排序性能越好;数据越接近有序,快速排序性能越差。

    空间复杂度: 在每次分割的过程中,需要 1 个空间存储枢值。而快速排序大概需要 logN次的分割。

    算法稳定性 : 相等元素可能会因为数据的交换导致前后顺序改变,所以快速排序是不稳定的。

    通常,快速排序被认为是平均性能最好的排序方法,时间复杂度为:O(nlogn)。

  • 相关阅读:
    java学习多线程之创建多线程一
    java学习之线程
    ios开发系统地图知识
    Swift3.0变化分享
    最新友盟6.1.1集成遇到的坑,自定义分享界面实现(跳转控制器做分享)
    IOS开发遇到(null)与<null>轻松处理
    友盟分享实现
    iOS 判断网络连接状态的几种方法
    GCD总结
    iOS视频边下边播--缓存播放数据流
  • 原文地址:https://www.cnblogs.com/zhichao-yan/p/13368502.html
Copyright © 2020-2023  润新知