面试常见排序算法(中)

转载:http://blog.csdn.net/he_shuai20/article/details/72720715

堆排序:堆排序是利用建堆过程中的向下调整算法,进行排序。升序排列时,应建立大堆,每次选出最大的堆顶的数,然后将堆顶的数据与最末端的数据交换,然后减小堆的大小,进行再次调整。重复以上操作即可。降序排列时,应建立小堆,与上述过程相同。

大小堆:


向下调整算法:

我引用殷人昆老师数据结构里面的给大家看看思想。


堆排序的代码为:

  1. void AjustDown(int* arr, int pos, int size)  //向下调整算法堆排序  
  2. {  
  3.     int parent = pos;  
  4.     int child = 2 * pos + 1;  
  5.     while (child <= size)  
  6.     {  
  7.         if (child<size && arr[child + 1] > arr[child])  
  8.         {  
  9.             child++;  
  10.         }  
  11.         if (arr[parent] < arr[child])  
  12.         {  
  13.             swap(arr[parent], arr[child]);  
  14.             parent = child;  
  15.             child = child * 2 + 1;  
  16.         }  
  17.         else  
  18.         {  
  19.             break;  
  20.         }  
  21.     }  
  22.   
  23. }  
  24.   
  25. void AjustDown(int* arr, int size)  
  26. {  
  27.     int parent = (size - 2) / 2;  
  28.     while (parent >= 0)  
  29.     {  
  30.         AjustDown(arr, parent, size-1);  
  31.         parent–;  
  32.     }  
  33. }  
  34. void HeapSort(int* arr, int size)//堆排序  
  35. {  
  36.         AjustDown(arr,size);  
  37.       
  38.       
  39.     while (size > 1)  
  40.     {  
  41.         int temp = arr[0];  
  42.         arr[0]=arr[size - 1];  
  43.         arr[size - 1] = temp;  
  44.         size–;  
  45.         AjustDown(arr,size);  
  46.     }  
  47.   
  48. }  
void AjustDown(int* arr, int pos, int size)  //向下调整算法堆排序
{
    int parent = pos;
    int child = 2 * pos + 1;
    while (child <= size)
    {
        if (child<size && arr[child + 1] > arr[child])
        {
            child++;
        }
        if (arr[parent] < arr[child])
        {
            swap(arr[parent], arr[child]);
            parent = child;
            child = child * 2 + 1;
        }
        else
        {
            break;
        }
    }

}

void AjustDown(int* arr, int size)
{
    int parent = (size - 2) / 2;
    while (parent >= 0)
    {
        AjustDown(arr, parent, size-1);
        parent--;
    }
}
void HeapSort(int* arr, int size)//堆排序
{
        AjustDown(arr,size);


    while (size > 1)
    {
        int temp = arr[0];
        arr[0]=arr[size - 1];
        arr[size - 1] = temp;
        size--;
        AjustDown(arr,size);
    }

}
计数排序:

思想:就是通过创建带排序数组中Max与Min的差值大小的数组,来统计带排序数组中所出现数值的个数,进而最终还原排序后的数组。

方法:1、计算待排序数组中Max与Min并计算差值newsize;

           2、开辟newsize大小的数组,以待排序数组数值-Nin为下标,对带排序数组的数值出现个数进行统计;

           3、对带排序数组进行还原;

计数排序的代码实现:

  1. void CountSort(int *arr, int size)  
  2. {  
  3.     int Max = arr[0];  
  4.     int Min = arr[0];  
  5.     for (int i = 0; i < size; ++i)  
  6.     {  
  7.         if (Max < arr[i])  
  8.             Max = arr[i];  
  9.         if (Min > arr[i])  
  10.             Min = arr[i];  
  11.     }  
  12.     int newsize = Max - Min + 1;  
  13.     int* a = new int[newsize];  
  14.     memset(a, 0, sizeof(int)*newsize);  
  15.     for (int i = 0; i < size; ++i)  
  16.     {  
  17.         a[arr[i] - Min]++;  
  18.     }  
  19.   
  20.     int j = 0;  
  21.     for (int i = 0; i < newsize; ++i)  
  22.     {  
  23.         while (a[i])  
  24.         {  
  25.             arr[j++] = i+Min;  
  26.             a[i]–;  
  27.         }  
  28.     }  
  29.     delete[] a;  
  30. }  
void CountSort(int *arr, int size)
{
    int Max = arr[0];
    int Min = arr[0];
    for (int i = 0; i < size; ++i)
    {
        if (Max < arr[i])
            Max = arr[i];
        if (Min > arr[i])
            Min = arr[i];
    }
    int newsize = Max - Min + 1;
    int* a = new int[newsize];
    memset(a, 0, sizeof(int)*newsize);
    for (int i = 0; i < size; ++i)
    {
        a[arr[i] - Min]++;
    }

    int j = 0;
    for (int i = 0; i < newsize; ++i)
    {
        while (a[i])
        {
            arr[j++] = i+Min;
            a[i]--;
        }
    }
    delete[] a;
}


快速排序由于方法比较多,在下次会给大家分享。同时对所有的排序方法的稳定性,时间复杂度,空间复杂度进行分析。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值