堆排序

堆排序

 

二叉堆的定义

二叉堆满足二个特性:

1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。

2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。

基本思想

             把每个叶子节点看作是一个堆,并从最后一个非叶子节点开始调整,保证以当前节点为根的子树被调整为堆,直至根节点即可。

建堆复杂度分析

           建堆复杂度是O(n),整体复杂度是O(nlogn)。

        构建堆从叶节点的父节点开始,以树高递减的方向逐层往上,一直到根。

        假设堆中共有N个元素,则树高H=log2(N),对于从树高为h的节点建堆的复杂度为O(H - h);

        从最底层开始,为从各节点建堆的复杂度求和:

        S = 1 * 2^(H-1) + 2 * 2^(H-2) + ... + (H-1) * 2^1 + H * 2^0

        = 2^H + 2^(H-1) + ... + 2^1 - H

        = 2^(H+1) - 2 - H

        将H=log2(N)代入,S = 2N - 2 - log2(N)

源代码

void myswap(int &a, int &b)
{
	int tmp = a;
	a = b;
	b = tmp;
}


//push element i down to a proper layer
//until the subtree rooted by i is adjusted to a heap
void minHeapFixdown(int heap[], int i, int n)
{
	int tmp = heap[i];
	int j = 2*i + 1;
	while(j < n)
	{
		if((j+1 < n) && heap[j+1] < heap[j])
			j++;
		if(tmp <= heap[j])
			break;
		heap[i] = heap[j];
		i = j;
		j = 2*i + 1;
	}
	heap[i]  = tmp;
}

//adjust the original array to a minheap
//fix the nodes down from the last midnode to the root node
void adjustMinHeap(int heap[],int n)
{
	for(int i = (n-1 -1)/2; i >= 0; i--)
		minHeapFixdown(heap,i,n);
}

//drop the top element to the last slot indexed as ind
//and maintain the array as minheap 
void dropElement(int heap[], int ind)
{
	myswap(heap[0], heap[ind]);
	minHeapFixdown(heap, 0, ind);
}

//iteratively drop the top element to the last available slot
void minHeapSort(int heap[], int n)
{
	adjustMinHeap(heap, n);
	for(int ind = n-1; ind >= 0; ind--)
	{
		dropElement(heap,ind);
	}
}

//fix the bottom element up to a proper layer
//require that the array is already adjusted as a minheap
void minHeapFixup(int heap[], int ind)
{
	int p = (ind-1)/2;
	int tmp = heap[ind];
	while(p >= 0)
	{
		if(heap[ind] >= heap[p])
			break;
		heap[ind] = heap[p];
		ind = p;
		p = (ind-1)/2;
	}
	heap[ind] = tmp;
}

//add a new value to the last slot not used as the bottom of the heap
//and fix it up
void addElement(int heap[], int ind, int value)
{
	heap[ind] = value;
	minHeapFixup(heap, ind);
}

int main(void)
{
	int heap[8] = {8,4,7,6,2};
	adjustMinHeap(heap, 5);
	addElement(heap, 5, 3);
	minHeapSort(heap, 6);
	
	for(int i = 0; i < 6; i++)
		cout<<heap[i]<<" "<<endl;
	cout<<endl;
	return 0;
}


 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值