堆排序C++

来源:互联网 发布:西方音乐史知乎 编辑:程序博客网 时间:2024/05/16 02:45
<span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13.9200000762939px; line-height: 20.8800010681152px; background-color: rgb(255, 255, 255);">1、堆</span>

  堆给人的感觉是一个二叉树,但是其本质是一种数组对象,因为对堆进行操作的时候将堆视为一颗完全二叉树,树种每个节点与数组中的存放该节点值的那个元素对应。所以堆又称为二叉堆,堆与完全二叉树的对应关系如下图所示:

  通常给定节点i,可以根据其在数组中的位置求出该节点的父亲节点、左右孩子节点,这三个过程一般采用宏或者内联函数实现。书上介绍的时候,数组的下标是从1开始的,所有可到:PARENT(i)=i/2  LEFT(i) = 2*i   RIGHT(i) = 2*i+1。

  根据节点数值满足的条件,可以将分为最大堆和最小堆。最大堆的特性是:除了根节点以外的每个节点i,有A[PARENT(i)] >= A[i],最小堆的特性是:除了根节点以外的每个节点i,有A[PARENT(i)] >=A[i]。

  把堆看成一个棵树,有如下的特性:

(1)含有n个元素的堆的高度是lgn。

(2)当用数组表示存储了n个元素的堆时,叶子节点的下标是n/2+1,n/2+2,……,n。

(3)在最大堆中,最大元素该子树的根上;在最小堆中,最小元素在该子树的根上。

2、保持堆的性质

  堆个关键操作过程是如何保持堆的特有性质,给定一个节点i,要保证以i为根的子树满足堆性质。书中以最大堆作为例子进行讲解,并给出了递归形式的保持最大堆性的操作过程MAX-HEAPIFY。先从看一个例子,操作过程如下图所示:

从图中可以看出,在节点i=2时,不满足最大堆的要求,需要进行调整,选择节点2的左右孩子中最大一个进行交换,然后检查交换后的节点i=4是否满足最大堆的要求,从图看出不满足,接着进行调整,直到没有交换为止。

#ifndef HEAP_H_#define HEAP_H_class Heap{private:int *A;int heapSize;                               //堆中元素的个数int Parent(int i){ return (int)(i / 2); }   //返回父节点的序号int Left(int i){ return 2 * i; }            //返回左孩子序号int Right(int i){ return (2 * i + 1); }     //返回右孩子序号void exchange(int &a, int &b){ int temp = a; a = b; b = temp; }public:Heap(int *Arr,int n);                       //构造函数,n为数组元素个数void MaxHeapity(int i);                     //维护最大堆void BuildMaxHeap();                        //建堆void HeapSort();                            //堆排序};//构造函数Heap::Heap(int *Arr,int n){A = Arr;heapSize = n;}//维护最大堆void Heap::MaxHeapity(int i){int left = Left(i + 1);int right = Right(i + 1);int largest;                              //存父节点,子节点的最大值if (left <= heapSize && A[left - 1] > A[i])largest = left - 1;elselargest = i;if (right <= heapSize && A[right - 1] > A[largest])largest = right - 1;if (largest != i){exchange(A[i], A[largest]);MaxHeapity(largest);}}//建最大堆void Heap::BuildMaxHeap(){for (int i = (int)(heapSize / 2); i >= 1; i--)MaxHeapity(i);}//堆排序void Heap::HeapSort(){BuildMaxHeap();for (int i = heapSize - 1; i >= 1; i--){exchange(A[0],A[i]);heapSize = heapSize - 1;MaxHeapity(0);}}#endif




测试:

#include <iostream>#include "Heap.h"using namespace std;int main(){int a[5] = {5,3,2,4,1};Heap heap1(a, 5);heap1.BuildMaxHeap();for (int i = 0; i < 5; i++)cout << a[i] << endl;return 0;}


0 0