给定关键码集合,用筛选法构建小顶堆,并按照层序遍历方式输出构建的堆中所有节点。

文章介绍了如何使用筛选法构建小顶堆,并通过层序遍历的方式输出构建的堆中所有节点。示例代码展示了C++中利用vector实现堆的构建和遍历的过程,包括sift_down()、build_heap()和print_tree()三个关键函数。
摘要由CSDN通过智能技术生成

题目:堆的构建 给定关键码集合,用筛选法构建小顶堆,并按照层序遍历方式输出构建的堆中所有节点。

输入样例: 19 8 35 65 40 3 7 45 输出样例: 3 8 7 45 40 35 19 65

示例代码中,我们首先定义了两个函数sift_down()和build_heap()来实现筛选法构建小顶堆的过程,以及一个函数print_tree()来按层序遍历输出所有节点。

sift_down()函数用于将给定的节点下移,以满足小顶堆的定义。该函数的参数包括一个向量nums,表示待构建小顶堆的数组,一个整数root,表示要下移的节点的索引,以及一个整数end,表示下移的最大范围。

在sift_down()函数中,我们首先找到根节点的左子节点,然后将其与右子节点进行比较,并找到两个子节点中较小的一个。然后,如果根节点的值大于其较小的子节点,就将其与较小的子节点交换,并将根节点更新为较小的子节点。然后,我们继续向下移动到较小的子节点,并重复上述过程,直到根节点的值小于或等于其子节点的值,或者已经到达下移的最大范围。

build_heap()函数用于构建小顶堆。该函数的参数为一个向量nums,表示待构建小顶堆的数组。在build_heap()函数中,我们从最后一个非叶节点开始,依次向上调用sift_down()函数,以构建小顶堆。

print_tree()函数用于按层序遍历输出小顶堆中所有节点。该函数的参数为一个向量nums,表示待输出的数组。在print_tree()函数中,我们通过循环遍历数组中的所有元素,并输出它们的值。

最后,在主函数中,我们定义了一个包含给定关键码的向量nums,并依次调用build_heap()函数和print_tree()函数,以构建小顶堆并输出所有节点。

输出结果应该是:

3 8 7 45 40 35 19 65

这就是按照层序遍历方式输出构建的小顶堆中所有节点的结果。

#include <iostream>
#include <vector>

using namespace std;

// 将堆的节点向下移动以满足堆的性质
void sift_down(vector<int>& nums, int root, int end);

// 用输入的数组建立堆
void build_heap(vector<int>& nums);

// 打印堆
void print_tree(vector<int>& nums);

int main() {
	vector<int> nums;
	int num;
	// 输入数组元素
	while (cin >> num) {
		nums.push_back(num);
		// 当遇到回车时停止输入
		if (cin.peek() == '\n') {
			break;
		}
	}
	build_heap(nums);
	print_tree(nums);
	return 0;
}

void print_tree(vector<int>& nums) {
	int n = nums.size();
	// 打印堆的元素
	for (int i = 0; i < n; i++) {
		cout << nums[i] << " ";
	}
	cout << endl;
}

void build_heap(vector<int>& nums) {
	int n = nums.size();
	// 从最后一个非叶子节点开始向下筛选
	for (int i = n / 2 - 1; i >= 0; i--) {
		sift_down(nums, i, n - 1);
	}
}

void sift_down(vector<int>& nums, int root, int end) {
	// 根据当前节点计算左子节点
	int child = root * 2 + 1;
	// 当左子节点存在时继续向下筛选
	while (child <= end) {
		// 比较左右子节点大小,如果右子节点更小则选取右子节点
		if (child + 1 <= end && nums[child] > nums[child + 1]) {
			child += 1;
		}
		// 如果根节点大于子节点,则交换它们,并继续向下筛选
		if (nums[root] > nums[child]) {
			swap(nums[root], nums[child]);
			root = child;
			child = root * 2 + 1;
		}
		// 否则说明已经满足堆的性质,停止筛选
		else {
			break;
		}
	}
}

vector 是 C++ 标准库中的一个动态数组容器,可以在程序运行时根据需要动态地分配内存。与 C 语言中的数组相比,vector
具有更高的灵活性和易用性,可以方便地进行插入、删除、查找等操作,同时也提供了许多方便的函数和算法来操作向量。

使用vector需要包含头文件,可以通过以下方式定义一个 vector 对象:

c++

#include using namespace std;

vector nums; // 定义一个存放 int 类型元素的 vector 对象

其中表示该 vector 对象存储的是 int 类型的元素。

vector 的优点在于它的大小和容量可以在运行时动态地改变,因此可以避免手动管理内存带来的麻烦。同时,vector
支持快速的随机访问和连续的内存分配,这使得它在许多场景下都比较高效。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值