C++数据结构 第三次作业

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

题目描述

有若干个节点,每个节点上都有编号,把这些节点随意地构成二叉树,请编程输出该二叉树的层次遍历序列。

输入

第一行是n(n小于100),表示有n个节点,每个节点按从1到n依次编号。第一行后有n行,每行三个正整数i、l、r,分别表示节点i及对应的左右孩子的编号,如果不存在孩子则以-1表示。三个整数之间用一个空格隔开。

输出

输出该二叉数的层次遍历序列。

样例输入 Copy

4
1 2 4
3 1 -1
2 -1 -1
4 -1 -1

样例输出 Copy

3 1 2 4
#include<bits/stdc++.h>
using namespace std;
struct treeNode
{
	int data,l,r;
};
void cenci(treeNode *tree,int root)
{
	int queue[100]={0},front=0,rear=0;
	queue[rear]=tree[root].data;rear++;
	while(queue[front]!=0)
	{
		if(tree[queue[front]].l!=-1)
		{
			queue[rear]=tree[queue[front]].l;
			rear++;
		}
		if(tree[queue[front]].r!=-1)
		{
			queue[rear]=tree[queue[front]].r;
			rear++;
		}
		cout<<queue[front]<<' ';
		front++;
	}
}
int main()
{
	int n,i,j;
	cin>>n;
	treeNode *tree=new treeNode[n+1];
	int judge[100]={0};
	for(i=0;i<n;i++)
	{
		cin>>j;
		tree[j].data=j;
		cin>>tree[j].l;
		if(tree[j].l!=-1)
		   judge[tree[j].l]=1;
		cin>>tree[j].r;
		if(tree[j].r!=-1)
		   judge[tree[j].r]=1;
	}
	int root=0;
	for(j=1;j<=n;j++)
	{
		if(judge[j]==0)
		   root=j;
	}
	cenci(tree,root);
	return 0;
}


问题 B: 小根堆的判定

题目描述

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

输入

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

输出

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

样例输入 Copy

2
30 26 27 88
5 6 7 8 9 10

样例输出 Copy

False
True
#include<bits/stdc++.h>
using namespace std;
struct arr{
	int a[100];
};
bool judge(int* a,int len)
{
	int i=0;
	bool flag=1;
	for(i=0;i<len;i++)
	{
		if(2*i+1<len&&2*i+2<len)
		{
			if(a[i]>a[2*i+1]||a[i]>a[2*i+2])
			{
				flag=0;
				break;
			}
		}
	
	}
	return flag;
}
int main()
{
	int n,j,num;
	cin>>n;
	bool flag[100];
	arr *cy=new arr[n];
	for(int i=0;i<n;i++)
	{
		j=0;
		while(cin>>num)
		{
			cy[i].a[j]=num;
			j++;
			if(cin.get()=='\n')
			{
				break;
			}
		}
		flag[i]=judge(cy[i].a,j);
	}
	for(int i=0;i<n;i++)
	{
		if(flag[i]==0) cout<<"False"<<endl;
		else cout<<"True"<<endl;
	}
	return 0;
}

问题 C: 最小堆的形成 

题目描述

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

输入

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

输出

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

样例输入 Copy

8
53 17 78 23 45 65 87 9

样例输出 Copy

9 17 65 23 45 78 87 53
#include<iostream>
using namespace std;
void mindui(int*a,int len,int i)
{
	int t;
	if(2*i+1<len)
	   mindui(a,len,2*i+1);
	if(2*i+2<len)
	   mindui(a,len,2*i+2);
	if(2*i+1<len||2*i+2<len)
	{
		if(2*i+1<len&&a[i]>a[2*i+1])
		{
			t=a[i];
			a[i]=a[2*i+1];
			a[2*i+1]=t;
		}
		if(2*i+2<len&&a[i]>a[2*i+2])
		{
			t=a[i];
			a[i]=a[2*i+2];
			a[2*i+2]=t;
		}
	}
}
int main()
{
	int n,i;
	cin>>n;
	int*a=new int[n];
	for(i=0;i<n;i++)
	{
		cin>>a[i];
	}
	for(i=0;i<n;i++)
		mindui(a,n,0);
	for(i=0;i<n;i++)
	{
		cout<<a[i]<<" ";
	}
}


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

题目描述

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

输入

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

输出

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

样例输入 Copy

5 5
0 1
2 0
1 3
1 4
4 2

样例输出 Copy

0 1 3 4 2
#include<bits/stdc++.h>
using namespace std;
int edge[101][101];
int n,m;
bool b[101]={0};
void dfs(int t)
{
	cout<<t<<" ";
	for(int i=1;i<=m;i++)
	{
		if(edge[t][i]&&!b[i])
		{
			b[i]=1;
			dfs(i);
		}
	}
}

int main()
{
	cin>>m>>n;
	int x,y;
	for(int i=1;i<=n;i++)
	{
		cin>>x>>y;
		edge[x][y]=1,edge[y][x]=1;
	}dfs(0);
	return 0;
}

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

题目描述

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

输入

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

输出

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

样例输入 Copy

5 5
0 1
2 0
1 3
1 4
4 2

样例输出 Copy

0 1 2 3 4
#include<bits/stdc++.h>
using namespace std;
int edge[101][101];
int n,m;
bool b[101]={0};
void bfs(int t)
{
	cout<<t<<" ";
	int q[101],front=1,rear=0;
	q[++rear]=t;
	b[t]=1;
	while(front<=rear)	
	{
		for(int i=1;i<=m;i++)
		{
			if(edge[q[front]][i]&&!b[i])
			{
				b[i]=1;
				q[++rear]=i;
				cout<<i<<" ";
			}
		}++front;
	}
} 

int main()
{
	cin>>m>>n;
	int x,y;
	for(int i=1;i<=n;i++)
	{
		cin>>x>>y;
		edge[x][y]=1,edge[y][x]=1;
	}bfs(0);
	return 0;
}

问题 F: 最小生成树 

题目描述

已知一个无向图G的顶点和边,顶点从0依次编号,请编程输出图G的最小生成树对应的边权之和。

输入

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

输出

最小生成树对应的边权之和。

样例输入 Copy

4 5
0 1 6
0 2 9
2 1 12
1 3 10
3 2 3

样例输出 Copy

18
#include<cstdio>
#include<iostream>
using namespace std;
const int maxSize = 1000;
const int INF = 2147483647;
int n, m, G[maxSize][maxSize];
int d[maxSize];
bool vis[maxSize] = { false };

int prim() {
	fill(d, d + maxSize, INF);
	d[0] = 0;
	int ans = 0;
	for (int i = 0; i < n; i++) {
		int u = -1, min = INF;
		for (int j = 0; j < n; j++) {
			if (vis[j] == false && d[j] < min) {
				u = j;
				min = d[j];
			}
		}
		//找不到小于INF的d[u]则剩下的顶点和集合s不连通
		if (u == -1) return -1;
		vis[u] = true;
		ans += d[u];
		for (int v = 0; v < n; v++) {
			if (vis[v] == false && G[u][v] != INF && G[u][v] < d[v]) {
				d[v] = G[u][v];
			}
		}
	}
	return ans;
}

int main(void) {
	int u, v, w;
	//n为顶点数, m为边数 
	cin>>n>>m;
	fill(G[0], G[0] + maxSize * maxSize, INF);
	for (int i = 0; i < m; i++) {
		cin>>u>>v>>w;
		G[u][v] = G[v][u] = w;
	}
	int ans = prim();
	cout<<ans;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

参宿七625

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值