各种排序算法分析与实现

版权声明:本文为博主原创文章,转载请附原文链接 https://blog.csdn.net/zujipi8736/article/details/86606353

说明:代码使用codeblocks编译,C++实现,个人编写,如有错误,还望指正。

fengjingtu

总结

排序方法 稳定性 平均时间复杂度 最优时间复杂度 最坏时间复杂度 空间复杂度
插入排序 稳定 O( n 2 n^{2} ) O( n n O( n 2 n^{2} 1
冒泡排序 稳定 O( n 2 n^{2} ) O( n 2 n^{2} O( n 2 n^{2} 1
二路归并排序 稳定 O( n l o g nlog )
二叉树排序 稳定 O( n l o g n nlogn )
计数排序 稳定 O( n + k n+k )
桶排序 不稳定 O(n)
选择排序 不稳定 O( n 2 n^{2} O( n 2 n^{2} O( n 2 n^{2} 1
堆排序 不稳定 O( n l o g n nlogn O( n l o g n nlogn O( n l o g n nlogn 1
希尔排序 不稳定 O( n l o g n nlogn
基数排序 不稳定 O( n + k n+k
快速排序 不稳定 O( n l o g n nlogn O( n l o g n nlogn O( n 2 n^{2} O( n l o g n nlogn

插入排序

插入排序把序列分为两个部分,一部分有序,一部分无序。每一次循环都把无序的第一个元素插入到有序的序列中。

以序列 {4,2,1,3,5}为例。

当一个序列中只有一个元素的时候,我们认为这个序列有序。所以最开始的时候,有序和无序序列如下:

{4|, 2,1,3,5}

接下来取无序中的第一个元素,和有序元素中的最后一个元素,也就是最大的元素比较,如果大于,则不需要移动,去下一个无序元素即可,如果小于,则一直交换到合适的位置。

取2和4比较,小于,则和4交换位置{2,4|,1,3,5},发现到达有序的第一个位置,则停止。

然后取1,和4比较,小于则交换{2,1,4|,3,5},继续和2比较交换{1,2,4|,3,5}至此1的位置也找到了。

接下来元素3,需要和4比较交换{1,2,3,4|,5},继续和2比较不交换,结束。

元素5 和4比较不交换,结束。

整个过程可以在原序列上直接操作,只需要一个临时的变量用于交换。所以空间复杂度认为是O(1);

时间上,如果本来是有序的队列,每个元素只需要和自己前一位的元素比较一次就可以完成排序,这个是最优时间复杂度:O(n),相反,如果这个一个倒序的序列,第n元素都需要和n-1个元素比较,这个时候是最坏时间复杂度:O(n2)。平均时间复杂度是O(n2);

插入排序是稳定的。

void insert_sort(int array[],int len)
{
    int v=0;
    int j=0;
    for(int i=1;i<len;i++)
    {
        v=array[i];
        for(j=i-1;j>=0;j--)
        {
            if(array[j]>v)
                array[j+1]=array[j];
            else
                break;
        }
        array[j+1]=v;
    }
}

冒泡排序

冒泡排序总是比较和交换相邻的两个元素。再一次循环中,获得到一个最大的值,把他交换到序列的最后,然后再剩下的序列中同样找到一个最大的数。

以序列 {4,2,1,3,5}为例。

寻找最大的数字,比较交换,放到最后:4和2比较交换。

{2, 4,1,3,5}

4和1比较交换:{2, 1,4,3,5}

4和3比较交换:{2, 1,3,4,5}

4和5比较不交换{2, 1,3,4,5},这一轮循环下来,得到了最大的值5:{2, 1,3,4,|5}

第二轮以同样的方式:2和1比较交换,2和3比较不交换,3和4比较不交换,得到{1, 2,3,|4,5}

在经过两轮的比较就完成了排序。

整个过程可以在原序列上直接操作,只需要一个临时的变量用于交换。所以空间复杂度认为是O(1);

时间上,不管序列是否有序,我们都需要进行比较,一共需要比较(n-1)轮,每轮比较的次数是n的线性表达式。我们认为最优。最坏。平均的时间复杂度都是O(n2)。

冒泡排序是稳定的。

void insert_sort(int array[],int len)
{
    int v=0;
    int j=0;
    for(int i=1;i<len;i++)
    {
        v=array[i];
        for(j=i-1;j>=0;j--)
        {
            if(array[j]>v)
                array[j+1]=array[j];
            else
                break;
        }
        array[j+1]=v;
    }
}

选择排序

void insert_sort(int array[],int len)
{
    int v=0;
    int j=0;
    for(int i=1;i<len;i++)
    {
        v=array[i];
        for(j=i-1;j>=0;j--)
        {
            if(array[j]>v)
                array[j+1]=array[j];
            else
                break;
        }
        array[j+1]=v;
    }
}

快速排序

快速排序采用分治法,把一个串,按照一个基准值分为左右两部分,将以同样的方式排序左右两部分,每一次调用的结果固定了基准值的最终位置。:在下面的代码中,基准值选择串尾的数,基准值左面都比它小,右面都比它大

int Partition(int array[],int len,int start,int end)
{
    if(array== NULL || len<=0 || start<0 || end>=len)
        return -1;
    int val=array[end];
    int devide=start;
    int tmp;
    for(int i=start;i<=end;i++)
    {
        if(array[i]<val)
        {
            tmp=array[devide];
            array[devide]=array[i];
            array[i]=tmp;
            devide++;
        }
    }
    tmp=array[devide];
    array[devide]=array[end];
    array[end]=tmp;
    return devide;
}
void quick_sort(int array[],int len,int start,int end)
{
    if(start==end)
        return ;
    int index=Partition(array,len,start,end);
    if(index > start)
        quick_sort(array,len,start,index-1);
    if(index < end)
        quick_sort(array,len,index+1,end);
}

堆排序

1、建最大堆。

2、把堆顶元素放在末尾。

3、把这个堆的最后一个元素删除,重新调整这个堆。

4、重复2、3;

void max_heap_adjust(int array[],int len,int i)
{
    int tmp=0;
    int left=2*i+1;
    int right=2*i+2;
    int m=0;
    if(left<=len)
    {
        m=left;
    }
    if(right<=len&&array[right]>array[m])
    {
        m=right;
    }
    if(m>i&&array[m]>array[i])
    {
        tmp=array[m];
        array[m]=array[i];
        array[i]=tmp;
        max_heap_adjust(array,len,m);
    }
}

void build_maxheap(int array[],int len)
{
//从最后一个有孩子的节点下标开始

    int last_father=len/2;
    for(int i=last_father;i>=0;i--)
    {
        max_heap_adjust(array,len,i);
    }
    return;
}

void heap_sort(int array[],int len)
{
    if(array==NULL || len<=0)
        return ;
        build_maxheap(array,len-1);
    int tmp;
    for(int i=len-1;i>0;i--)
    {
        tmp=array[0];
        array[0]=array[i];
        array[i]=tmp;
        max_heap_adjust(array,i-1,0);
    }

    return ;
}

猜你喜欢

转载自blog.csdn.net/zujipi8736/article/details/86606353
今日推荐