zoukankan      html  css  js  c++  java
  • 排序算法学习之交换排序(冒泡排序,快速排序)

    冒泡排序

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


    步骤:

    进行第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)。

  • 相关阅读:
    周末之个人杂想(十三)
    PowerTip of the DaySorting Multiple Properties
    PowerTip of the DayCreate Remoting Solutions
    PowerTip of the DayAdd Help to Your Functions
    PowerTip of the DayAcessing Function Parameters by Type
    PowerTip of the DayReplace Text in Files
    PowerTip of the DayAdding Extra Information
    PowerTip of the DayPrinting Results
    Win7下IIS 7.5配置SSAS(2008)远程访问
    PowerTip of the DayOpening Current Folder in Explorer
  • 原文地址:https://www.cnblogs.com/zhichao-yan/p/13368502.html
Copyright © 2011-2022 走看看