9.7 堆排序基础知识准备

堆排序基础知识: 

#include 
//堆排序
//因为堆是一棵完全二叉树,固可用数组来表示
const int maxn=100;
int heap[maxn],n=10;//heap 为堆,n为元素个数
//堆由上向下调整:将每个结点V与其孩子比较,若有比其大的,则交换他们的位置
//直到没有比他大的或没有孩子结点

//对heap数组在[low,high]范围下进行向下调整
//其中low为欲调整结点的数组下标,high一般为堆的数组的最后一个元素的数组下标
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存储右孩子下标 
	}
	//如果孩子中最大的权值比欲调整结点i大
	if(heap[j]>heap[i])
	{
		swap(heap[i],heap[j]);//交换
		i=j;//保持i为欲调整结点,j为i的左孩子 
		j=2*i; 
	}
	else
		break;//孩子的权值均比欲调整结点小,调整结束 
}

//建堆:由于完全二叉树的叶子结点为n/2向上取整,因此数组下标在[1,n/2]范围内的结点都是非叶结点。
//于是可以从n/2的位置倒着枚举结点,因为每调整完一个结点,权值最大的结点就会在根结点的位置,这样可以保证每个结点都是以其为根的子树中权值最大的结点

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

//如果要删除最大元素(堆顶)并让其保持堆的结构,只需让最后一个元素覆盖堆顶元素,然后对根结点调整即可
//删除堆顶元素
void deletetop()
{
	heap[1]=heap[n--];
	downadjust(1,n);
}

//往堆中添加元素,将元素添加至数组最后,然后向上调整

void upadjust(int low,int high)
{
	int i=high,j=i/2;//i为欲调整结点,j为其父亲结点
	while(j>=low)
	{
		if(heap[i]>heap[j])
		{
			swap(heap[j],heap[i]);
			i=j;
			j=i/2;
		}
		else
			break;
	} 
}

//添加元素x
void insert(int x)
{
	heap[++n]=x;
	upadjust(1,n);
}

//堆排序
void heapsort()
{
	createheap();
	for(int i=n;i>1;--i)//倒着枚举,直至堆中只有一个元素 
	{
		swap(heap[i],heap[1]);//交换heap[i]与堆顶
		downadjust(1,i-1); 
	}
}

 

你可能感兴趣的:(堆排序,基础算法)