堆排序和建立最大堆
2017-10-21 10:23
253 查看
参考:http://www.cnblogs.com/beaglebone/p/5876745.html
堆排序和建立最大堆
堆是完全二叉树的结构,因此对于一个有n个节点的堆,高度为O(logn)。最大堆:堆中的最大元素存放在根节点的位置。
除了根节点,其他每个节点的值最多与其父节点的值一样大。也就是任意一个子树中包含的所有节点的值都不大于树根节点的值。
堆中节点的位置编号都是确定的,根节点编号为1,每一层从左到右依次编号。由堆是完全二叉树,可以知道当堆中某个节点的编号为i时,如果这个节点有左右子树,那么左子树的节点编号为2*i,右子树的节点编号为2*i+1(当然这是在根节点编号为1的情况时)。
并且有n个节点的堆中叶子节点的编号为从n/2+1~n。因为假设节点n/2+1不是叶子节点,那么它的左子节点编号(n/2+1)*2=n+1,而节点总共只有n个。完全二叉树的叶子节点只出现在最下面两层。最下层的叶子集中在左边,倒数二层的叶子集中在右边。
维护最大堆函数MAX_HEAPWEIHU(A,i),假定节点i的左右子树已经是最大堆。那么维护堆时,先比较i节点的值与左右节点值的大小,将三个数中的最大值交换到根节点的位置。假设根节点i与左子节点的值交换了,那么左子树就要再次调用MAX_HEAPWEIHU(A,2*i),判断左子树还是不是最大堆,如果是则结束,否则继续调用进行维护。因此调用MAX_HEAPWEIHU(A,i)的时间复杂度为O(logn)。
void heapfy(int a[],int i,int heapsize) { int largest=i; int left=2*i+1; int right=left+1; if(left<heapsize && a[i]<a[left]) largest=left; if(right<heapsize && a[largest]<a[right]) largest=right; if(largest!=i) { swap(a[i],a[largest]); heapfy(a,largest); } }
建立最大堆:将A[1,n]数组转换为最大堆。因为最大堆为完全二叉树结构,因此A[n/2+1],……,A
是最大堆的叶子节点。每个叶子节点本身就是一个最大堆,所以我们就要从A[n/2]~A[1]逐步维护这个最底层的最大堆(调用MAX_HEAPWEIHU(A,i)维护)。
void buildheap(int a[],int len) { for(int i=len/2-1;i>=0;i--) heapfy(a,i,len); }
堆排序:先建立一个最大堆。然后将最大堆的A[1]与A
交换,然后从堆中去掉这个节点n,通过减少A.heap_size的值来实现。剩余的节点中,新的根节点可能违背了最大堆的性质,因此需要调用MAX_HEAPWEIHU(A,1)来维护最大堆。
void sortheap(int a[],int len) { for(int i=n-1;i>=0;i--) { swap(a[0],a[i]); heapfy(a,0,i); } }
#include<iostream> using namespace std; void heapfy(int a[],int index,int heapsize) { int left=index*2+1; int right=left+1; int largest=index; if(left<heapsize&&a[index]<a[left]) largest=left; if(right<heapsize&&a[largest]<a[right]) largest=right; if(largest!=index) { swap(a[index],a[largest]); heapfy(a,largest,heapsize); } } void heapsort(int a[],int len) { for(int i=len/2-1;i>=0;i--) { heapfy(a,i,len); } for(int i=len-1;i>=0;i--) { swap(a[i],a[0]); heapfy(a,0,i); } } int main() { int a[10]={9,3,4,5,1,8,0,2,7,6}; heapsort(a,10); }
相关文章推荐
- c++实现最大堆建立(链表结构)和堆排序
- c++实现最大堆建立(链表结构)和堆排序
- c++实现最大堆建立(链表结构)和堆排序
- c++实现最大堆建立(链表结构)和堆排序
- 最大堆的建立和堆排序
- 堆排序查找前N个最大数和二分查找算法
- 堆排序(最大堆)
- C语言 最大堆排序
- 堆排序 (建立大顶堆)
- 大数据处理堆实现N个数据找K个最大数据和堆排序
- C++实现堆、最大堆、最小堆 -- 堆排序插入删除操作
- 用堆排序寻找数组中最大的K个数
- 计算机算法--最大堆实现堆排序(从大到小输出)
- c++使用vector建立最大堆和最小堆
- 如何根据一个数组建立最大堆
- 数据结构中堆的建立,建小堆,以及堆排序
- 最大堆和利用堆排序
- Java排序算法--建立堆和堆排序(转)
- 最大堆排序
- 第6章 堆排序 java实现 简单版 泛型版 最大优先级队列