堆排序
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; }