0
点赞
收藏
分享

微信扫一扫

[建堆&堆排序的时间复杂度推导]向上建堆&向下建堆&堆排序的时间复杂度分析推导

前导知识:求二叉树的节点个数

满二叉树的节点个数

最后一层只有一个节点的二叉树的节点个数

最后一层仅有一个节点的二叉树
公式推导


向下建堆的时间复杂度推导

向下建堆代码

// 向下调整函数
// n是指堆中有效元素的数量, parent是指堆顶的元素
// 需要比较子节点哪个大哪个小
void AdjustDown(HPDataType* a, int n,int parent)
{
	// 先假设左孩子大
	int child = parent * 2 + 1;
	while (child < n)// 当child>=n时就说明child已经到达叶子节点了
	{
		// 先找出左右孩子节点中大的那个
		if (child + 1 < n && a[child + 1] > a[child])// 说明假设错误,交换小的那个子节点
		{
			child++;
		}
		// 和父亲节点进行比较
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

向下建堆的时间复杂度推导


向上建堆的时间复杂度推导

向上建堆代码

// 向上调整函数
void AdjustUp(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child)
	{
		// 大堆调整
		if (a[child] > a[parent])
		{
			Swap(&a[child], a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		// 若已经满足大堆,那么就跳出循环
		else
		{
			break;
		}
	}
}

向上建堆复杂度推导


堆排序的时间复杂度推导

堆排序代码

// 对数组进行堆排序,需要建堆
void HeapSort(int* a, int n)
{
	// 降序,建小堆
	// 升序,建大堆
	for (int parent = (n-1-1)/2; parent > 0; parent--)
	{
		AdjustDown(a, n, parent);
	}
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		end--;
	}
}

堆排序的时间复杂度推导


举报

相关推荐

时间复杂度_空间复杂度

时间复杂度分析

0 条评论