矿业大学 2022数据结构实验三


问题 A 任意二叉树的层次遍历

有若干个节点,每个节点上都有编号,把这些节点随意地构成二叉树,请编程输出该二叉树的层次遍历序列。
输入:第一行是n(n小于100),表示有n个节点,每个节点按从1到n依次编号。第一行后有n行,每行三个正整数i、l、r,分别表示节点i及对应的左右孩子的编号,如果不存在孩子则以-1表示。三个整数之间用一个空格隔开。
输出:该二叉数的层次遍历序列。

样例输入:
4
1 2 4
3 1 -1
2 -1 -1
4 -1 -1
样例输出:
3 1 2 4

#include<iostream>
#include<stack>
#include<queue>
#include<string>
using namespace std;
struct node {
	char a;
	node* left;
	node* right;
	node() { left = right = NULL; }
};
struct work {
	int a, b, val;
	
};
node* convert(work* x, int a) {
	node* p = new node;
	p->a = x[a].val+'0';
	if (x[a].a != -1) { p->left = convert(x, x[a].a); }
	if (x[a].b != -1) { p->right = convert(x, x[a].b); }
	return p;
}
class tree {
	node* root;
public:
	tree() { root = new node; }
	
	void create() {
		int n; cin >> n; int r;
		work* x = new work[n];
		for (int i = 0; i < n; i++)
			cin >> x[i].val >> x[i].a >> x[i].b;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (x[i].val == x[j].a) {
					x[j].a = i;
					break;
				}
				else if (x[i].val == x[j].b) {
					x[j].b = i;
					break;
				}
				if (j == n - 1)
					r=i;
			}
		}
		
		root = convert(x, r);
		
	}
	void qx(node *q) {
		cout << q->a ;
		if (q->left != NULL)qx(q->left);
		if (q->right != NULL)qx(q->right);
	}
	void zx(node* q) {
		if (q->left != NULL)zx(q->left);
		cout << q->a;
		if (q->right != NULL)zx(q->right);
	}
	void hx(node* q) {
		if (q->left != NULL)hx(q->left);
		if (q->right != NULL)hx(q->right);
		cout << q->a;
	}
	void ccbl(node* q) {
		queue<node>s;
		s.push(*q);
		node* p;
		while(!s.empty()){
			p = &s.front();
			cout << p->a << ' ';
			if (p->left != NULL) {
				s.push(*p->left);
			}
			if (p->right != NULL) {
				s.push(*p->right);
			}
			s.pop();
		}
	}
	node* getr() { return root; }
};
int* test(int n) {
	int* x = new int[n];
	for (int i = 0; i < n; i++)
		cin >> x[i];
	return x;
}
int main() {
	tree a;
	a.create();
	a.ccbl(a.getr());
}

问题 B: 小根堆的判定

题目描述

堆是以线性连续方式存储的完全二叉树,小根堆的每一个元素都不大于其左右孩子,现在给你n个完全二叉树数组存储序列,请编程判定相应完全二叉树数组存储序列是否为小根堆。

输入

第一行n(n<100),表示有n组测试用例。后边的n行,每一行都是相应完全二叉树数组存储序列(序列最长为100)。

输出

对应相应完全二叉树数组存储序列,判定为小根堆的输出True,否则输出False。

样例输入

2
30 26 27 88
5 6 7 8 9 10
样例输出

False
True

#include<iostream>
#include<string>
using namespace std;
int main()
{
	int n; cin >> n;
	int x[100][500],y[100];
	for (int i = 0; i < n; i++) {
		int k = 0;
		while (1) {
			cin >> x[i][k++];
			if (cin.get() == '\n')break;
		}
		y[i] = k;
	}
	for (int i = 0; i < n; i++) {
		bool flag(true); int j = 0;
		int m = y[i]-1;
		while (flag) {
			if (2 * j + 1 > m)break;
			if (x[i][j] > x[i][2 * j + 1]) {
				
				flag = 0; break;
			}
			if (2 * j + 2 > m)break;

			if (x[i][j] > x[i][2 * j + 2]) {
				flag = 0; break;
			}
			j++;
		}
		if (!flag)cout << "False" << endl;
		else { cout << "True" << endl; }

	}
}

问题 C: 最小堆的形成

题目描述

现在给你n个结点的完全二叉树数组存储序列,请编程调整为最小堆,并输出相应最小堆的存储序列。

输入

第一行是n,第二行是n个结点的完全二叉树数组存储序列。

输出

输出相应最小堆的存储序列。

样例输入

8
53 17 78 23 45 65 87 9
样例输出

9 17 65 23 45 78 87 53

#include<iostream>
#include<string>
using namespace std;
void swap(int *x,int n,int k) {
	if (2 * k + 1 < n) {
		swap(x, n, 2 * k + 1);
		if (x[2 * k + 1] < x[k]) {
			int temp(x[k]);
			x[k] = x[2 * k + 1];
			x[2 * k + 1] = temp;
		}
		swap(x, n, 2 * k + 1);
	}
	if (2 * k + 2 < n) {
		swap(x, n, 2 * k + 2);
		if (x[2 * k + 2] < x[k]) {
			int temp(x[k]);
			x[k] = x[2 * k + 2];
			x[2 * k + 2] = temp;
		}
		swap(x, n, 2 * k + 2);
	}
}
int main()
{
	int n; cin >> n;
	int* x = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> x[i];
	}
	swap(x, n, 0);
	for (int i = 0; i < n; i++) {
		cout << x[i] << ' ';
	}
}

问题 D 无向图的深度优先搜索

题目描述

已知一个无向图G的顶点和边,顶点从0依次编号,现在需要深度优先搜索,访问任一邻接顶点时编号小的顶点优先,请编程输出图G的深度优先搜索序列。

输入

第一行是整数m和n(1<m,n<100),分别代表顶点数和边数。后边n行,每行2个数,分别表示一个边的两个顶点。

输出

该图从0号顶点开始的深度优先搜索序列。

样例输入

5 5
0 1
2 0
1 3
1 4
4 2
样例输出

0 1 3 4 2

没用栈,感觉用栈太麻烦了

#include<iostream>
using namespace std;
void sd(bool**x,bool*y,int a,int n) {
	if (y[a] == 0) {
		cout << a << ' ';
		y[a] = true;
	}
	for (int i = 0; i < n; i++) {
		if (x[a][i] == 1&&y[i]==0)sd(x,y,i,n);
	}
}
int main()
{
	int n, m; cin >> n >> m;//顶点和边数
	bool** x = new bool*[n];
	bool* y = new bool[n];
	for (int i = 0; i < n; i++) {
		x[i] = new bool[n];
		for (int j = 0; j < n; j++) {
			x[i][j] = 0;
		}
		y[i] = 0;
	}
	for (int i = 0; i < m; i++) {
		int a, b; cin >> a >> b;
		x[a][b] = x[b][a] = 1;
	}
	sd(x, y, 0, n);
}

问题 E: 无向图的广度优先搜索

题目描述

已知一个无向图G的顶点和边,顶点从0依次编号,现在需要广度优先搜索,访问任一邻接顶点时编号小的顶点优先,请编程输出图G的广度优先搜索序列。

输入

第一行是整数m和n(1<m,n<100),分别代表顶点数和边数。后边n行,每行2个数,分别表示一个边的两个顶点。

输出

该图从0号顶点开始的广度优先搜索序列。

样例输入

5 5
0 1
2 0
1 3
1 4
4 2
样例输出

0 1 2 3 4

#include<iostream>
#include<queue>
using namespace std;
queue<int>s;
void gd(bool**x,bool*y,int a,int n) {
	while (!s.empty()) {
		int q = s.front();
		cout << q << ' ';
		s.pop();
		for (int i = 0; i < n; i++) {
			if (x[q][i] == 1&&y[i]==0) {
				s.push(i); y[i] = 1;
			}
		}

	}
}
int main()
{
	int n, m; cin >> n >> m;//顶点和边数
	bool** x = new bool*[n];
	bool* y = new bool[n];
	for (int i = 0; i < n; i++) {
		x[i] = new bool[n];
		for (int j = 0; j < n; j++) {
			x[i][j] = 0;
		}
		y[i] = 0;
	}
	for (int i = 0; i < m; i++) {
		int a, b; cin >> a >> b;
		x[a][b] = x[b][a] = 1;
	}
	s.push(0); y[0] = 1;
	gd(x, y, 0, n);
}

问题 F 最小生成树

已知一个无向图G的顶点和边,顶点从0依次编号,请编程输出图G的最小生成树对应的边权之和。
第一行是整数m和n(1<m,n<100),分别代表顶点数和边数。后边n行,每行3个数,分别表示一个边的两个顶点和该边的权值。
最小生成树对应的边权之和。
4 5
0 1 6
0 2 9
2 1 12
1 3 10
3 2 3
18

#include<iostream>
#include<queue>
using namespace std;
int minval(bool*y,int **z,int n) {
	int amin = 0, mini=0, min;
	for (int o = 0; o < n - 1; o++) {
		min = 5000;
		for (int j = 0; j < n; j++) {
			int mintemp=5000,minitemp;
			if (y[j] == 1) {
				int i;
				for (i = 0; i < n; i++) 
				{
					if (y[i] == 1)continue;
					if (z[j][i] < mintemp) {
						mintemp = z[j][i];
						minitemp = i;
					}
				}
			}
			else continue;
			if (min > mintemp) {
				min = mintemp;
				mini = minitemp;
			}
		}
		y[mini] = 1;
		amin += min;
	}
	return amin;
}
int main()
{
	int n, m; cin >> n >> m;//顶点和边数
	bool** x = new bool*[n];
	bool* y = new bool[n];
	int** z = new int* [n];
	for (int i = 0; i < n; i++) {
		x[i] = new bool[n]; z[i] = new int[n];
		for (int j = 0; j < n; j++) {
			x[i][j] = 0;
			z[i][j] = 9999;
		}
		y[i] = 0;
	}
	for (int i = 0; i < m; i++) {
		int a, b,val; cin >> a >> b>>val;
		z[a][b] = z[b][a] = val;
	}
	y[0] = 1;
	cout << minval( y, z, n);
}

把0写成o了,是说for循环怎么出不去QAQ

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值