问题 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;
}