(二叉)堆数据结构是一种数组对象,如下图所知,他可以被视为一颗完全二叉树。
其有如下性质:
1)对于i节点(i表示下标),其父节点为Li/2」,左孩子节点为2i,右孩子节点为2i+1
2)最大堆满足:A[PARENT(i)] ≥ A[i] ;最小堆满足:A[PARENT(i)] ≤ A[i]
3)堆的高度为:Θ(lgn)
4)子数组元素A[ (Ln/2」+1)...n]是树中的所有叶子节点
维持堆的性质
以最大堆为例,当节点i违反了最大堆的性质,则需从节点i处“下降”以调整堆。伪代码如下:其时间复杂度为:T(n)=O(h)
EG:
建堆
根据上述性质4,对于数组A,建堆伪代码如下:其时间复杂度为:T(n)=O(n)
堆排序
伪代码如下:其时间复杂度为:T(n)=O(nlgn)
EG:
......
堆排序完整代码如下:
#include<iostream>
#define PARENT(i) (i/2)
#define LEFT(i) (2*i)
#define RIGHT(i) (2*i+1)
using namespace std;
void Print(int *a,int n)
{
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
int *Transform(int *a,int n)
{
int * A=new int[n+1];
A[0]=n;
for(int i=0;i<n;i++)
A[i+1]=a[i];
return A;
}
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
void Max_Heapify(int *A,int i)
{//adjust the heap to maintain the heap property
int heap_size=A[0];
int l=LEFT(i) ; //index of i's left child
int r=RIGHT(i);
int largest; //At each step,the largest of the element A[i],A[LEFT(i)]
//A[RIGHT(i)] is determined,and its index is stored in largest.
if(l<=heap_size && A[l]>A[i])
largest = l;
else
largest = i;
if(r<=heap_size && A[r]>A[largest])
largest = r;
if(largest!=i) //the subtree rooted at i violate the max-heap property
{
swap(A[i],A[largest]);
Max_Heapify(A,largest); //after exchanging ,the subtree rooted at largest might violate the max-heap property
}
}
void Build_MaxHeap(int *A)
{//Transform array A into max-heap A,where A[0]=heap-size
int A_length=A[0];
for(int i=A_length/2;i>=1;i--)
Max_Heapify(A,i);
}
void Heap_Sorting(int *A)
{
Build_MaxHeap(A);
int heap_size=A[0];
for(int i=heap_size;i>=2;i--)
{
swap(A[1],A[i]);
heap_size--;
A[0]=heap_size; //After build-maxheap,A[0] store the heap-size,which is changing
Max_Heapify(A,1);//adjust the heap to be max-heap from the root
}
}
int main(){
int a[]={4,1,3,2,16,9,10,14,8,7};
int n=sizeof(a)/sizeof(int);
int *A=new int[n+1];
cout<<"Before Sorting A[1..n]:"<<endl;
A=Transform(a,n); //Transform a[0...n-1] into a[1...n];a[0]=a.length
Print(A,n);
cout<<"After Heap_Sorting A[1..n]:"<<endl;
Heap_Sorting(A);
Print(A,n);
return 0;
}
运行结果:
[注:若有错误,请指正~]