zoukankan      html  css  js  c++  java
  • 常用排序算法总结

    冒泡排序

    时间复杂度:O(N²)

     

    原理:从数组的第个位置开始两两比较array[index]和array[index+1],如果array[index]大于array[index+1]则交换array[index]和array[index+1]的位置,直到数组结束。

    void Bubble(int array[], int size)
    {
        int i,j;
    
        for(i=0; i<size; i++)
        {
            for(j=i+1; j<size; j++)
            {
                if(array[i]>array[j])
                {
                    array[i]=array[i]^array[j];
                    array[j]=array[i]^array[j];
                    array[i]=array[j]^array[i];
                }
            }
        }

    二、选择排序

    时间复杂度:O(N^2),与冒泡排序相比减少了数组交换的次数

     

    原理:选择个 array[0]作为标杆,然后循环找到除这个外最小的 (查找小于标杆的最小 ),交换这两个,这时最小就被放到了array[0]上,然后再将array[1]作为标杆,从剩下未排序的 中找到最小 ,并交换。

    void Sort(int array[], int size)
    {
        int i,j,k;
    
        for(i=0; i<size; i++)
        {
            k=i;
            for(j=i+1; j<size; j++)
            {
                if(array[j]<array[k])
                {
                    k=j;
                }
            }
    
            if(i!=k)
            {
                array[i]=array[i]^array[k];
                array[k]=array[k]^array[i];
                array[i]=array[i]^array[k];
            }
        }
    }

    三、插入排序

    时间复杂度:插入排序对随即顺序的序列的时间复杂度也为O(N^2),但是对于基本有序的序列进行排序时间复杂度为O(N)

    适用:一般不用在数据大于1000的场合或者重复排序超过200数据项的序列使用插入排序

     

    原理:插入排序的思想是数组是部门有序的,然后将无序的部分循环插入到已有序的序列中。

    void InsertSort(int array[], int size)
    {
        int i,j,temp;
    
        for(i=2; i<size; i++)
        {
            temp=array[i];
    
            for(j=i-1; j>=0 && array[j]>temp; j--)
            {
                array[j+1]=array[j];
            }
    
            array[j+1]=temp;
        }
    
    }

    四、希尔排序/缩小增量排序

    时间复杂度:n的1.2次幂

    适用:适合于数据量在5000以下并且速度并不是特别重要的场合。

    原理:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

    void shellSort(int array[], int size)
    {
        int i,j,temp;
        int increment=size;
    
        do
        {
            increment=increment/3+1;
            for(i=increment+1; i<size; i++)
            {
                temp=array[i];
    
                for(j=i-increment; j>=0 && array[j]>temp; j-=increment)
                {
                    array[j+increment]=array[j];
                }
    
                array[j+increment]=temp;
            }
        }while(increment>1);
    
    }

    五、堆排序

    时间复杂度:O(N*logN)

    适用:适合于数据量非常大的场合(百万数据)

    原理:利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。
    其基本思想为(大顶堆):
    1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无须区;
    2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
    3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

    //array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度
    //本函数功能是:根据数组array构建大根堆
    void HeapAdjust(int array[],int i,int nLength)
    {
        int nChild;
        int nTemp;
        for(;2*i+1<nLength;i=nChild)
        {
            //子结点的位置=2*(父结点位置)+1
            nChild=2*i+1;
            //得到子结点中较大的结点
            if(nChild<nLength-1&&array[nChild+1]>array[nChild])++nChild;
            //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点
            if(array[i]<array[nChild])
            {
                nTemp=array[i];
                array[i]=array[nChild];
                array[nChild]=nTemp;
            }
            else break; //否则退出循环
        }
    }
    //堆排序算法
    void HeapSort(int array[],int length)
    {
        int i;
        //调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素
        //length/2-1是最后一个非叶节点,此处"/"为整除
        for(i=length/2-1;i>=0;--i)
        HeapAdjust(array,i,length);
        //从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
        for(i=length-1;i>0;--i)
        {
            //把第一个元素和当前的最后一个元素交换,
            //保证当前的最后一个位置的元素都是在现在的这个序列之中最大的
            array[i]=array[0]^array[i];
            array[0]=array[0]^array[i];
            array[i]=array[0]^array[i];
            //不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
            HeapAdjust(array,0,i);
        }
    }
  • 相关阅读:
    通过数据归一化提高WPF绘图效率
    WPF 利用路径动画做一个环形加载动画
    WPF 实现简易事件聚合
    WPF 使用渐变色在绘图中灵活应用
    WPF 使用DrawingVisual和DispatchFrame快速提升绘图速度
    本地Nuget包管理
    飞腾芯片 中标麒麟 安装mysql
    飞腾平台 银河麒麟 安装nginx
    mysql8的配置优化
    国产化之路-国产操作系统安装.net core 3.1 sdk
  • 原文地址:https://www.cnblogs.com/274914765qq/p/4379409.html
Copyright © 2011-2022 走看看