时间:2019-02-21
本文章向大家介绍堆,主要包括堆使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

堆的定义与基本操作

堆的数组定义:

const int maxn = 100;
int heap[maxn] , n = 10;//heap为堆,n为元素个数 

向下调整的代码:

void downAdjust(int low,int high){
	int i = low,j = i * 2;              //i为欲调整结点,j为其左孩子 
	while(j <= high ){                  //存在孩子结点 
		if(j+1 <= high && heap[j+1] > heap[j]){ //如果右孩子存在,且右孩子的值大于左孩子 
			 j = j + 1;                 //让j存储右孩子下标 
		}               
		if(heap[j] > heap[i]){          //如果孩子中最大的权值比欲调整结点i大 
			swap(heap[j],heap[i]);      //交换最大权值的孩子与欲调整结点i 
			i = j;                      //保持i为欲调整结点,j为i的左孩子 
			j = i*2;
		}else{
			break;                      //孩子的权值均比欲调整结点i小,调整结束 
		}
	}
} 

建堆的代码:

void createHeap(){
	for(int i = n / 2;i >= 1;i--){
		downAdjust(i,n);
	}
}

删除堆顶元素代码:

void deleteTop(){
	heap[1] = heap[n--];//用最后一个元素覆盖堆顶元素,并让元素个数减1
	downAdjust(1,n);    //向下调整堆顶元素
}

向上调整的代码:

void upAdjust(int low,int high){
	int i = high,j = i / 2;//i为欲调整结点,j为其父亲 
	while(j >= low){       //父亲在[low,high]范围内 
		if(heap[j] < heap[i]){//父亲权值小于欲调整结点i的权值 
			swap(heap[j],heap[i]);//交换父亲和欲调整结点 
			i = j;                //保持i为欲调整结点,j为i的父亲 
			j = i / 2;
		}else{
			break;//父亲权值比欲调整结点i的权值大,调整结束 
		}
	}
} 

添加元素的代码:

void insert(int x){
	heap[n++] = x; //让元素个数加1,然后将数组末位赋值为x 
	upAdjust(1,n); //向上调整新加入的结点n 
} 

堆排序

堆排序代码如下:

void heapSort(){
	createHeap();            //建堆 
	for(int i = n;i > 1;i--){//倒着枚举,直到堆中只有一个元素 
		swap(heap[i],heap[1]);//交换heap[i]与堆顶 
		downAdjust(1,i - 1); //调整堆顶 
	}
}