C++中七大排序算法

这里的七大指的是快速排序、堆排序、归并排序、希尔排序、选择排序、插入排序和冒泡排序,由于桶排序应用场景有限,这里就不写了。先对比一下这几种排序的效率:

观察表发现一个有趣的现象:对于堆排序和归并排序,他们的最好、最坏和平均的时间复杂度都是O(nlogn),也就是说数据的初始化顺序对这两种算法是没有影响的。先来一个直观的比较(500000条数据)

直观来看,快速排序、堆排序和归并排序的时间在一个数量级上,接着是希尔排序,最后是插入排序、选择排序和冒泡排序。至于排序原理我就不再说了,直接贴代码。

//快速排序  
int Paration(int a[], int low, int high)  
{  
    int key = a[low];  
    while ( low < high )  
    {  
        while (low < high && a[high] >= key ) high--;  
        a[low] = a[high];  
  
        while (low < high && a[low] <= key ) low++;  
        a[high] = a[low];         
    }  
    a[low] = key;  
    return low;  
}  
void QuickSort(int a[], int low, int high)  
{  
    if ( low < high )  
    {  
        int index = Paration(a, low, high);  
        QuickSort(a, low, index - 1);  
        QuickSort(a, index + 1, high);  
    }  
}  

调用:QuickSort(a, 0, N - 1);

 

//堆排序  
void HeapAdjust(int a[], int n, int k)  
{  
    int l = 2 * k + 1;  
    int r = 2 * k + 2;  
  
    if ( l >= n && r >= n ) return;  
  
    int key = a[k];  
    int left = 0x80000000;  
    int right = 0x80000000;  
      
    if ( l < n ) left  = a[l];  
    if ( r < n ) right = a[r];  
    if ( key >= left && key >= right ) return;  
  
    if ( left > right )  
    {  
        a[k] = a[l];  
        a[l] = key;  
        HeapAdjust(a, n, l );  
    }  
    else  
    {  
        a[k] = a[r];  
        a[r] = key;  
        HeapAdjust(a, n, r);  
    }  
}  
  
void HeapSort(int a[], int n)  
{  
    //初始化堆的时候是对所有的非叶子结点进行筛选。
    //最后一个非终端元素的下标是[n/2]向下取整,所以筛选只需要从第[n/2]向下取整个元素开始,从后往前进行调整。
    for ( int i = ( n - 1 ) / 2; i >= 0; --i )   
    {  
        HeapAdjust(a, n, i);  
    }  
    while ( n )  
    {  
        int t = a[0];  
        a[0] = a[n-1];  
        a[n-1] = t;  
        n -= 1;  
        HeapAdjust(a, n, 0);  
    }  
}  

调用:HeapSort(a, N);

 

//归并排序  
void Merage(int a[], int low, int mid, int high, int tmp[])  
{  
    int len1 = mid - low + 1;  
    int len2 = high - mid;  
    memcpy(tmp, a + low, len1 * sizeof(int));  
    memcpy(tmp + len1, a + mid + 1, len2 * sizeof(int));  
      
    int index = low;  
    int i = 0;  
    int j = len1;  
    while ( i < len1 && j < len1 + len2 )  
    {  
        if (tmp[i] < tmp[j])  
        {  
            a[index++] = tmp[i++];  
        }  
        else  
        {  
            a[index++] = tmp[j++];  
        }  
    }  
    while ( i < len1 )        a[index++] = tmp[i++];  
    while ( j < len1 + len2 ) a[index++] = tmp[j++];  
}  
  
void MergeSort(int a[], int low, int high)  
{  
    static int *tmp = new int[high];  
    if ( low < high )  
    {  
        int mid = (low + high) / 2;  
        MergeSort(a, low, mid);  
        MergeSort(a, mid + 1, high);  
        Merage(a, low, mid, high, tmp);  
    }  
}  

调用:MergeSort(a, 0, N - 1);

 

//希尔排序  
void ShellSort(int a[], int n)  
{  
    int step[] = {37, 31, 23, 19, 17, 13, 11, 7, 3, 1}; //步长  
    for ( int k = 0; k < 10; ++k )  
    {  
        for (int i = step[k]; i < n; ++i )  
        {  
            int t = a[i];  
            int j = i - step[k];  
            for ( ; j >= 0 && t < a[j]; j -= step[k] )  
            {  
                a[j + step[k]] = a[j];  
            }  
            a[j + step[k]] = t;  
        }  
    }  
}  

调用:ShellSort(a, N);

 

//插入排序  
void InsertSort(int a[], int n)  
{  
    for ( int i = 1; i < n; ++i )  
    {  
        int t = a[i];  
        int j = i - 1;  
        for ( ; j >= 0 && t < a[j]; --j )  
        {  
                a[j + 1] = a[j];  
        }  
        a[j+1] = t;  
    }  
}  

调用:InsertSort(a, N);  有没有发现希尔排序和插入排序很像,其实希尔排序就是插入排序,只不过步长不是1。

 

//选择排序  
void SelectSort(int a[], int n)  
{  
    for ( int i = 0; i < n; ++i )  
    {  
        int min = a[i];  
        int index = i;  
        for ( int j = i + 1; j < n; ++j )  
        {  
            if (a[j] < min )  
            {  
                index = j;  
                min = a[j];  
            }  
        }  
        a[index] = a[i];  
        a[i] = min;  
    }  
}  

调用:SelectSort(a, N);

 

//冒泡排序  
void BubbleSort(int a[], int n)  
{  
    for (int i = 0; i < n; ++i)  
    {  
        for ( int j = 0; j < n - i - 1; ++j)  
        {  
            if ( a[j] > a[j+1] )  
            {  
                int t = a[j];  
                a[j] = a[j+1];  
                a[j+1] = t;  
            }  
        }  
    }  
}  

调用:BubbleSort(a, N);

有没有发现,代码越简单的效率越低。需要注意的是在上面的写法中,调用快速排序和归并排序时,传入的参数数最后一个元素的下标,而不是数组的大小,就是说N - 1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值