您的位置:首页 > 其它

堆排序

2014-08-25 11:09 176 查看

堆排序

二叉堆的定义

二叉堆满足二个特性:
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。

基本思想

把每个叶子节点看作是一个堆,并从最后一个非叶子节点开始调整,保证以当前节点为根的子树被调整为堆,直至根节点即可。

建堆复杂度分析

建堆复杂度是O(n),整体复杂度是O(nlogn)。

构建堆从叶节点的父节点开始,以树高递减的方向逐层往上,一直到根。

假设堆中共有N个元素,则树高H=log2(N),对于从树高为h的节点建堆的复杂度为O(H - h);

从最底层开始,为从各节点建堆的复杂度求和:

S = 1 * 2^(H-1) + 2 * 2^(H-2) + ... + (H-1) * 2^1 + H * 2^0

= 2^H + 2^(H-1) + ... + 2^1 - H

= 2^(H+1) - 2 - H

将H=log2(N)代入,S = 2N - 2 - log2(N)

源代码

void myswap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}

//push element i down to a proper layer
//until the subtree rooted by i is adjusted to a heap
void minHeapFixdown(int heap[], int i, int n)
{
int tmp = heap[i];
int j = 2*i + 1;
while(j < n)
{
if((j+1 < n) && heap[j+1] < heap[j])
j++;
if(tmp <= heap[j])
break;
heap[i] = heap[j];
i = j;
j = 2*i + 1;
}
heap[i]  = tmp;
}

//adjust the original array to a minheap
//fix the nodes down from the last midnode to the root node
void adjustMinHeap(int heap[],int n)
{
for(int i = (n-1 -1)/2; i >= 0; i--)
minHeapFixdown(heap,i,n);
}

//drop the top element to the last slot indexed as ind
//and maintain the array as minheap
void dropElement(int heap[], int ind)
{
myswap(heap[0], heap[ind]);
minHeapFixdown(heap, 0, ind);
}

//iteratively drop the top element to the last available slot
void minHeapSort(int heap[], int n)
{
adjustMinHeap(heap, n);
for(int ind = n-1; ind >= 0; ind--)
{
dropElement(heap,ind);
}
}

//fix the bottom element up to a proper layer
//require that the array is already adjusted as a minheap
void minHeapFixup(int heap[], int ind)
{
int p = (ind-1)/2;
int tmp = heap[ind];
while(p >= 0)
{
if(heap[ind] >= heap[p])
break;
heap[ind] = heap[p];
ind = p;
p = (ind-1)/2;
}
heap[ind] = tmp;
}

//add a new value to the last slot not used as the bottom of the heap
//and fix it up
void addElement(int heap[], int ind, int value)
{
heap[ind] = value;
minHeapFixup(heap, ind);
}

int main(void)
{
int heap[8] = {8,4,7,6,2};
adjustMinHeap(heap, 5);
addElement(heap, 5, 3);
minHeapSort(heap, 6);

for(int i = 0; i < 6; i++)
cout<<heap[i]<<" "<<endl;
cout<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: