数据结构-堆

       为了自己的方便记忆吧,复习了一下堆这种数据结构。写一遍就会加深印象。

   堆,是一种完全二叉树,所以具有完全二叉树的所有性质,在这里我们会用到的最重要的一条性质就是,若设完成二叉树共有n个节点,那么,最后一个非叶节点是n/2。(注意:编程时,一般我们用数组的下标是从0开始的)我们可以利用这个性质,在构建堆和筛选的过程中,不必去遍历所有的节点,从而节省了时间。(为什么呢?因为:从第n/2+1个节点到第n个节点都为叶子节点,我们在筛选和构建堆时,就是要比较父节点和子节点的值,现在叶子节点是没有孩子的,所以不用去遍历。)

   堆,分为大根堆和小根堆。如果父亲节点的值大于左右子孩子的值,而且孩子节点也满足此性质,那么就是大根堆,相反就是小根堆。堆的构建和筛选过程,是一个逐步向根节点走的过程,这样可以保证每一个节点都满足堆的性质。

   我们以小根堆为例吧。我懒得画图来分析,别的博客上都有很详细的介绍,我直接上代码吧。构建堆的代码,可以用递归和非递归,两种我都写了一遍,以下代码在本人电脑上visual studio2010运行正常,若有发现错误,请批评指正。

非递归:

void CreateHeap(int data[],int len)	// 非递归
{
	int p = len / 2 - 1;
	while(p >= 0 && p < len)
	{
		int q = 2 * p + 1;
		if(q < len)
		{
			if(q < len - 1 && data[q+1] < data[q])
				q++;
			if(data[q] < data[p])
			{
				int tmp = data[p];
				data[p] = data[q];
				data[q] = tmp;

				int n = 2 * q + 1;
				if((n < len && data[n] < data[q]) || (n < len - 1 && data[n+1] < data[q]))
					p = q;
				else
					p--;
			}
			else
				p--;
		}
	}
}

递归:

void CreateHeapR(int data[],int p, int len)	// 递归
{
	if(p >= 0 && p < len)
	{
		int q = 2 * p + 1;
		if(q < len)
		{
			if(q < len - 1 && data[q+1] > data[q])
				q++;
			if(data[q] > data[p])
			{
				int tmp = data[p];
				data[p] = data[q];
				data[q] = tmp;

				int n = 2 * q + 1;
				if((n < len && data[n] > data[q]) || (n < len - 1 && data[n+1] > data[q]))
					CreateHeapR(data,q,len);
				else
					CreateHeapR(data,--p,len);	
			}
			else
				CreateHeapR(data,--p,len);
			
		}
	}
}

    以上就是堆的构建和筛选过程。而对于堆排序,我们可以直接利用上面的函数来实现。用堆排序的过程就是:先将二叉树的根节点输出,然后,将最后一个叶子节点赋给根节点,并进行筛选。重复以上步骤,直到输出所有的节点。以小根堆为例,这个输出的序列就是一个有序的序列。堆构造和筛选过程时间复杂度为O(logn),而排序过程需要n次的筛选过程,所以时间复杂度为O(n*logn)。

    堆排序代码:

 

void HeapSort(int data[],int len)
{
	if(len <= 1)
		return;
	CreateHeap(data,len);
	
	while(len)
	{
		cout << data[0] << " ";
		data[0] = data[len-1];
		len--;
		CreateHeap(data,len);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值