赞
踩
首先建立一个最大堆或者最小堆,需要进行max-heapify,build-max-heap过程,这里的2个过程也是最最核心和重要的,堆排序和优先队列都是建立在此基础上的。好废话不多说,我们来看看他们都是怎么构造这些巧妙的结构的吧
max-heapify过程,需要明确的是首先堆是个完全二叉树结构,而最大堆就是他的每个子树的父节点都比子节点要大,最小堆就刚好相反。max-heapify过程就是输入一个数组A和下标i,并且以i节点为父节点的左右子树都是最大堆,当A[i]可能小于其子女,也就是不符合最大堆的定义,我们要想办法调整整个数组结构使他符合定义。我们假定数组数组的左儿子节点为2×i,右儿子为2×i+1,事实上这样构造的二叉树刚刚好填满整个数组。算了下面的调整过程我用代码描述好了,文字太罗嗦,效果反而不好。
void maxheapify(int A[],int i,int heapsize)//最大堆}
这个过程的时间复杂度是logn,也就是树的最大高度。
接下来是build-max-heap的过程,之所以在max-heapify之后才建立这个过程是因为,要用到前者来构建最大堆。好了我说一下实现的具体思路
首先给你一个无序的数组,教你把它构建出一个最大堆,你怎么办。。很容易想到2个思路,一个从根节点进行构建,一个是从叶节点进行构建。首先从根节点进行构建的话,很容易否定,因为他的左右子树也是无序状态,没有最大堆的结构。而从叶子节点构建的话,就刚好弥补了前面的。首先叶子节点本身是最大堆,因为他没有子树了。然后再利用前面maxheapify过程进行保持最大堆的性质。从叶节点的父节点开始不断维护直到根节点,就完成了最大堆的构建。下面是c++代码
void buildheap(int A[])
{
for(int i=strlen(A)/2;i>=1;i--)
{
maxheapify(A,i,strlen(A);
}
}
这个过程的中复杂度也是比较优秀的,貌似平均是n,直观上是nlogn,有了这个究可以进行堆排序了。只要你每次弹出最大堆的根节点,然后再进行一次维护久可以了,代码也是比较巧妙的。
heapsort(int A[])
{
buildheap(A);
int s=strlen(A);
while(s>1) //将最大数和堆中最后一个数交换,然后使堆的大小减少1,再进行维护。
{
int temp=A[1];
A[1]=A[s];
A[s]=temp;
s--
heapify(A,1,s);
}
}
有点事先写到这儿吧。队列的插入什么的在晚些我会补回来
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。