刚才聊了一会天,思路有点乱了,努力整理了一下!!!
二叉堆其实就是像生成树一样的方式:
其中还是有一些很nice的约束,就拿其中一个三角节点来看,要求父节点的值一定要大于两个子节点的值,然后为了满足这个约束,下面就产生了一些约束生成的伪代码:
算法伪代码:
MAX-HEAPIFY(A,I)
1. l <- LEFT(i) //其中 i,l,r都为上述图片中圆圈外的数组标号,这里将 l 赋值为 i 标号数值为父节点的左子节点标号
2. r <-RIGHT(I) //将 r 赋值为 i 标号数值为父节点的右子节点标号
3. if l <-heap-size[A] and A[l] >A[i] //其中heap-size[A]为该数组的总个数]
4. then largest <- l //如果左节点数值大于父节点数值,就将子节点标号记录下
5. else largest <- i //如果子节点数值不大于父节点数值,就还是记录父节点标号
6. if r <=heap-size(A) and A[r] >A[largest] //将右节点的数值与现任最大数值的节点进行比较
7. then largest <- r //如果大于原最大值,就记录下此时的标号
8. if largest != i //如果最大值所在的标号不是原本父节点的标号,就将父节点数值与最大值所在标号数值进行交换
9. then exchange A[i] <- A[largest]
10. MAX-HEAPIFY(A,largest)
(将数组转化为二叉堆形式)算法伪代码:
BUILD-MAX-HEAP(A)
1. heap-size[A] <- length[A]
2. for i <- length[A]/2 downto 1 //这里有个很有趣的东西,length[A]/2之后得到的标号总是位于最后一个三角节点的父节点标号
3. do MAX-HEAPIFY(A,i)
(这里还是从底层开始建立二叉堆,其实本质上还是利用了递归的方法进行冒泡排序,每次冒出最大值)
C++:
main.cpp
#include <iostream>
#include<algorithm>
#include<iterator>
#include<functional>
using namespace std;
int main(){
int h[]={4,1,3,2,16,9,10,14,8,7};
make_heap(h,h+10,less<int>());//STL中拥有函数模板用来做堆建立;
cout<<"max heap:"<<endl;
copy(h,h+10,ostream_iterator<int>(cout," "));
cout<<endl;
make_heap(h,h+10,greater<int>());
cout<<"min heap:"<<endl;
copy(h,h+10,ostream_iterator<int>(cout," "));
cout<<endl;
}
JAVA:
LinearList.java
public class LinearList{
public static int left(int i) {
return 2*i+1;//由于数组一开始下标为0,所以跟标号为0,再大环境中更改为数组标号
}
public static int right(int i) {
return 2*i+2;
}
public static int parent(int i) {
if(i%2==1)
return i/2;
return i/2-1;
}
public static void heapify(List<Comparable> a,int i,int heapSize,Comparator comp) {
int l=left(i),r=right(i),most;
if((l<heapSize)&&(comp.compare(a.get(l), a.get(i))>0))
most=l;
else
most=i;
if((r<heapSize)&&(comp.compare(a.get(r), a.get(most))>0))
most=r;
if(most!=i) {
Collections.swap(a,i,most);
heapify(a,most,heapSize,comp);
}
}
public static void buildHeap(List<Comparable> a,Comparator comp) {
int heapSize=a.size();
for(int i=heapSize/2;i>=0;i--)
heapify(a,i,heapSize,comp);
}
}
Test.java
package test;
import java.util.*;
public class Test{
public static void main(String[] args){
int h[]= {4,1,3,2,16,9,10,14,8,7},i;
Vector<Integer> H=new Vector<Integer>();
for(i=0;i<10;i++)
H.add(new Integer(h[i]));
LinearList.buildHeap((List)H, new Greater());//比较后大的提升到父节点
System.out.println("max heap:");//最大二叉堆
System.out.println(H);
LinearList.buildHeap((List)H, new Less());//比较后小的提升到父节点
System.out.println("min heap:");//最小二叉堆
System.out.println(H);
}
}