堆排序

来源:互联网 发布:专业流量监控软件 编辑:程序博客网 时间:2024/06/08 11:10

锦标赛进化而来的  选择排序 ----堆排序

//1,首先从第length/2个元素开始,到第一个元素,为止,开始建立堆

//2,堆顶元素与最后一个元素对调,(这就开始排序啦。。)然后再调整堆顶元素(也就是第一个元素,下标为0)至 第length -1 个元素 //     为堆,再对调堆顶元素,如此循环。。。就排序好了

// 如上可知,如果非递减有序,则应建立大顶堆,反之亦然

 

#include <iostream>

using namespace std;

//比较函数
bool LT(const int a, const int b)
{
    return a < b;
}
//非递减排序
//假设val[s...m]中只有val[s]不满足堆条件,本函数调整val[s]为一个大顶堆 注:堆以顺序存储结构存储
//需要一个辅助存储空间temp
void heap_adjust(int val[],int s, int m)
{
    int temp = val[s];
    for (int j = 2 * s; j < m; j *= 2)
    {
        if (j < m && LT(val[j],val[j+1]))//按最大的子结点向下筛选
        {
            ++j;
        }
        if (!LT(temp,val[j]))  //temp 应插入在s位置上
        {
            break; 
        }
        val[s] = val[j];  //交换两值
        s = j;            //需要验证堆条件的位置下移
    }//for(int j..)
    val[s] = temp;
}//heap_adjust

//对顺序表val进行堆排序 length 为val长度 
void heap_sort(int val[], int length)
{
    for (int i = (length / 2) - 1; i >= 0; --i)   //注意数组下标是从0开始
    {
        heap_adjust(val,i,length);
    }//for
    int temp;
    for (int i = length - 1; i > 0; --i)
    {
        temp = val[i];
        val[i] = val[0];              //注意下标从0开始 如果不小心改为1 就出错啦。。
        val[0] = temp;

        //取走堆顶后,再堆调整一次
        heap_adjust(val,0,i-1);   //注意下标从0开始 如果不小心改为1 就出错啦。。
    }//for
}//heap_sort

int main()
{
    int val[] = {49,38,65,97,76,13,27,49};
    int len = sizeof(val) / sizeof(int);
    //cout << len << endl;
    cout << "before heap_sort: " << endl;
    for (int i = 0; i < len; i++)
    {
        cout << val[i] << endl;
    }
    cout << "heap_sort start..." << endl;
    heap_sort(val,len);
    cout  << "heap_sort end..." << endl;
    cout << "after the heap_sort ... " << endl;
    for (int i = 0; i < len; i++)
        cout << val[i] << endl;
    return 0;
}

 

//OK。

堆排序时间复杂度在最坏的情况下也是O(nlogn),这是比快排要好的地方。当然,堆排序不适宜小数据量的排序,因为建堆要花一些时间,小数据量直接用插入排序就好。快排在最坏情况下时间复杂度为O(n^2),一般情况下为O(nlogn)。

堆排序空间复杂度为O(1),快速排序空间复杂度为O(nlogn)(递归调用)。

这两种排序方法都适宜大数据量的排序,具有很大的优势。

原创粉丝点击