• 堆排序


    http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.4.2.2.htm

    :(二叉)堆数据结构是一种数组对象。它可以被视为一棵完全二叉树,树中每个结点与数组中存放该结点值的那个元素对应。

    二叉堆有两种:最大堆和最小堆(小根堆)。

    最大堆:所有节点的子节点比其自身小的堆。
    最小堆:所有节点的子节点比其自身大的堆。

    堆排序:堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单

    在堆排序算法中,使用的是最大堆,最小堆通常在构造优先级队列时使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    
    /*
    * Author: Tanky Woo
    * Blog:   www.WuTianQi.com
    * Data:   2010.12.20
    * Note:   堆排序(Heap Sort)
    */
    #include <iostream>
    using namespace std;
     
    // 输出当前堆的排序状况
    void PrintArray(int data[], int size)
    {
        for (int i=1; i<=size; ++i)
            cout <<data[i]<<"  ";
        cout<<endl;
    }
     
    // 堆化,保持堆的性质
    // MaxHeapify让a[i]在最大堆中"下降",
    // 使以i为根的子树成为最大堆
    void MaxHeapify(int *a, int i, int size)
    {
    	int lt = 2*i, rt = 2*i+1;
    	int largest;
    	if(lt <= size && a[lt] > a[i])
    		largest = lt;
    	else
    		largest = i;
    	if(rt <= size && a[rt] > a[largest])
    		largest = rt;
    	if(largest != i)
    	{
    		int temp = a[i];
    		a[i] = a[largest];
    		a[largest] = temp;
    		MaxHeapify(a, largest, size);
    	}
    }
     
    // 建堆
    // 自底而上地调用MaxHeapify来将一个数组a[1..size]变成一个最大堆
    //
    void BuildMaxHeap(int *a, int size)
    {
    	for(int i=size/2; i>=1; --i)
    		MaxHeapify(a, i, size);
    }
     
    // 堆排序
    // 初始调用BuildMaxHeap将a[1..size]变成最大堆
    // 因为数组最大元素在a[1],则可以通过将a[1]与a[size]互换达到正确位置
    // 现在新的根元素破坏了最大堆的性质,所以调用MaxHeapify调整,
    // 使a[1..size-1]成为最大堆,a[1]又是a[1..size-1]中的最大元素,
    // 将a[1]与a[size-1]互换达到正确位置。
    // 反复调用Heapify,使整个数组成从小到大排序。
    // 注意: 交换只是破坏了以a[1]为根的二叉树最大堆性质,它的左右子二叉树还是具备最大堆性质。
    //        这也是为何在BuildMaxHeap时需要遍历size/2到1的结点才能构成最大堆,而这里只需要堆化a[1]即可。
    void HeapSort(int *a, int size)
    {
    	BuildMaxHeap(a, size);
    	PrintArray(a, size);
     
    	int len = size;
    	for(int i=size; i>=2; --i)
    	{
    		int temp = a[1];
    		a[1] = a[i];
    		a[i] = temp;
    		len--;
    		MaxHeapify(a, 1, len);
    		cout << "中间过程:";
    		PrintArray(a, size);
    	}
     
    }
     
    int main()
    {
    	int size;
    	int arr[100];
    	cout << "Input the num of elements:\n";
    	cin >> size;
    	cout << "Input the elements:\n";
    	for(int i=1; i<=size; ++i)
    		cin >> arr[i];
    	cout << endl;
        HeapSort(arr, size);
    	cout << "最后结果:";
        PrintArray(arr, size);
    }

    算法分析
         堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。
         堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均性能较接近于最坏性能。
         由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。
         堆排序是就地排序,辅助空间为O(1),
         它是不稳定的排序方法。

  • 相关阅读:
    实战DeviceIoControl 之五:列举已安装的存储设备
    在NT中直接访问物理内存
    实战DeviceIoControl 之三:制作磁盘镜像文件
    实战DeviceIoControl 之六:访问物理端口
    程序员的十层楼(转)
    Vista + VS2005 源代码绑定的问题
    敬告天下IT业主
    手动卸载windows服务
    古墓丽影9的截屏
    白领饮食十大“夺命”恶习(转)
  • 原文地址:https://www.cnblogs.com/lovemo1314/p/2175032.html
Copyright © 2020-2023  润新知