堆排序

1.建堆。n个数存放于数组里,下表从1到n。叶子下标则是:n/2+1, n/2+2...n。建堆的时候从最后一个非叶子节点到第一个节点,不断进行调整。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;

void MaxHeapify(int maxHeap[], int n, int nowPos) {
	int left, right, largest;
	left = nowPos << 1;
	right = (nowPos<<1|1);
	largest = nowPos;
	if(left <= n && maxHeap[left] > maxHeap[nowPos]) 
		largest = left;
	if(right <= n && maxHeap[right] > maxHeap[largest]) 
		largest = right;
	if(largest != nowPos) {
		swap(maxHeap[nowPos], maxHeap[largest]);
		MaxHeapify(maxHeap, n, largest);
	}
	
}

void buildMaxHeap(int maxHeap[], int n) {
	for(int i = n/2; i >= 1; --i) 
		MaxHeapify(maxHeap, n, i);
}


int main() {
	int maxHeap[50] = {0, 4, 1, 3, 2, 16, 9, 10, 14, 8, 7};
	buildMaxHeap(maxHeap, 10);
	return 0;
}

 2.堆排序。先用buildMaxHeap将输入的数组A[1...n]建成大顶堆。因为最大元素在A[1],交换A[1]和A[n]将数放入最终的位置,接着用MaxHeapify()调整A[1...n-1]建成大顶堆,不断重复这个过程。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;

void MaxHeapify(int maxHeap[], int n, int nowPos) {
	int left, right, largest;
	left = nowPos << 1;
	right = (nowPos<<1|1);
	largest = nowPos;
	if(left <= n && maxHeap[left] > maxHeap[nowPos]) 
		largest = left;
	if(right <= n && maxHeap[right] > maxHeap[largest]) 
		largest = right;
	if(largest != nowPos) {
		swap(maxHeap[nowPos], maxHeap[largest]);
		MaxHeapify(maxHeap, n, largest);
	}
	
}

void buildMaxHeap(int maxHeap[], int n) {
	for(int i = n/2; i >= 1; --i) 
		MaxHeapify(maxHeap, n, i);
}

void HeapSort(int maxHeap[], int n) {
	buildMaxHeap(maxHeap, 10);
	for(int i = n; i >= 2; --i) {
		swap(maxHeap[1], maxHeap[i]);
		MaxHeapify(maxHeap, i-1, 1);
	}
}

int main() {
	int maxHeap[50] = {0, 4, 1, 3, 2, 16, 9, 10, 14, 8, 7};
	HeapSort(maxHeap, 10);
	for(int i = 1; i <= 10; ++i) printf("%d ", maxHeap[i]);
	return 0;
}

 3.建堆效率。很容易会以为建堆的效率是nlogn,因为外层n的循环里还有个沿着树自上而下的调整。实际效率为o(n)。

假设一棵平衡二叉树的高度为h,则第一层的节点数为2^0,最后一层非叶子节点的节点数为2^(n-2)。最后一层非叶子节点要调整的深度为1,向上依次为2,3...n-1。

所以,建堆总的时间:

T=2^(h-2)*1 + 2^(h-3)*2 + ... + 2^1 * (h-2) + 1 * (h-1); (1)式   (1)*2可得

2*T=2^(h-1)*1 + 2^(h-2)*2 + ... + 2^2*(h-2) + 2*(h-1); (2)式     (2)-(1)得

2T-T = T = 2^(h-1) + 2^(h-2) + ...+ 2^1 - h + 1 = 2^h - h - 1;

又h = logn,所以T = n + logn + 1;故效率为o(n)。

 

 

posted on 2013-10-11 17:00  CrazyAC  阅读(233)  评论(0编辑  收藏  举报