问题 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
using namespace std;
#include
struct Node{
int left,right;
};
void preOrder(Node ntr[],int k){
cout<<k<<" ";
if(ntr[k].left!=-1) preOrder(ntr,ntr[k].left);
if(ntr[k].right!=-1) preOrder(ntr,ntr[k].right);
}
void levelOrder(Node ntr[],int k){
queue<int> Q;
Q.push(k);
while(!Q.empty()){
cout<<Q.front()<<" ";
if(ntr[Q.front()].left!=-1) Q.push(ntr[Q.front()].left);
if(ntr[Q.front()].right!=-1) Q.push(ntr[Q.front()].right);
Q.pop();
}
cout<<endl;
}
void Show(Node ntr[],int root[],int n){
for(int i=1;i<=n;i++){
if(root[i]){
levelOrder(ntr,i);
}
}
}
int main(){
int n;
cin>>n;
Node* ntr=new Node[n+1];
int* root=new int[n+1];
for(int i=1;i<=n;i++) root[i]=1;
int x,y,z;
for(int i=0;i<n;i++){
cin>>x>>y>>z;
ntr[x].left=y;
ntr[x].right=z;
if(y!=-1)root[y]=0;
if(z!=-1)root[z]=0;
}
Show(ntr,root,n);
return 0;
}
问题 B: 小根堆的判定
题目描述
堆是以线性连续方式存储的完全二叉树,小根堆的每一个元素都不大于其左右孩子,现在给你n个完全二叉树数组存储序列,请编程判定相应完全二叉树数组存储序列是否为小根堆。
输入
第一行n(n<100),表示有n组测试用例。后边的n行,每一行都是相应完全二叉树数组存储序列(序列最长为100)。
输出
对应相应完全二叉树数组存储序列,判定为小根堆的输出True,否则输出False。
样例输入
2
30 26 27 88
5 6 7 8 9 10
样例输出
False
True
#include
using namespace std;
int judge(int s[],int count){
for(int i=0;i<count;i++){
if((2*i+1)<count&&s[i]>s[2*i+1]||(2*i+2)<count&&s[i]>s[2*i+2]) return 0;
}
return 1;
}
int main(){
int n;
cin>>n;
int test[100];
int k,count;
int ans[n];
for(int i=0;i<n;i++){
count=0;
while(cin>>k){
test[count++]=k;
if(cin.get()== '\n') break;
}
ans[i]=judge(test,count);
}
for(int i=0;i<n;i++){
if(ans[i]==0){
cout<<"False"<<endl;
}else if(ans[i]==1){
cout<<"True"<<endl;
}
}
return 0;
}
问题 C: 最小堆的形成
题目描述
现在给你n个结点的完全二叉树数组存储序列,请编程调整为最小堆,并输出相应最小堆的存储序列。
输入
第一行是n,第二行是n个结点的完全二叉树数组存储序列。
输出
输出相应最小堆的存储序列。
样例输入
8
53 17 78 23 45 65 87 9
样例输出
9 17 65 23 45 78 87 53
#include
using namespace std;
void siftUp(int heap[],int start){
int j=start,i=(j-1)/2,temp=heap[j];
while(j>0){
if(heap[i]<=temp) break;
else{
heap[j]=heap[i];j=i;i=(i-1)/2;
}
}
heap[j]=temp;
}
int main(){
int n;
cin>>n;
int heap[n];
for(int i=0;i<n;i++){
cin>>heap[i];
siftUp(heap,i);
}
for(int i=0;i<n;i++){
cout<<heap[i]<<" ";
}
cout<<endl;
return 0;
}
问题 D: 无向图的深度优先搜索
题目描述
已知一个无向图G的顶点和边,顶点从0依次编号,现在需要深度优先搜索,访问任一邻接顶点时编号小的顶点优先,请编程输出图G的深度优先搜索序列。
输入
第一行是整数m和n(1
输出
该图从0号顶点开始的深度优先搜索序列。
样例输入
5 5
0 1
2 0
1 3
1 4
4 2
样例输出
0 1 3 4 2
#include
#include
using namespace std;
class Graph{
private:
int n;
int** edge;
public:
Graph(int n):n(n){
edge=new int*[n];
for(int i=0;i<n;i++){
edge[i]=new int[n];
for(int j=0;j<n;j++){
if(i==j)edge[i][j]=0;
else edge[i][j]=-1;
}
}
}
void insertEdge(int v1,int v2){
edge[v1][v2]=1;
edge[v2][v1]=1;
}
int getFirst(int v1){
for(int i=0;i<n;i++){
if(edge[v1][i]==1){
return i;
}
}
return -1;
}
int getNext(int v1,int v2){
for(int i=v2+1;i<n;i++){
if(edge[v1][i]==1){
return i;
}
}
return -1;
}
void DFS(int v,bool visited[]){
cout<<v<<" ";
visited[v]=true;
int w=getFirst(v);
while(w!=-1){
if(visited[w]==false)DFS(w,visited);
w=getNext(v,w);
}
}
void DFS(int v){
bool* visited=new bool[n];
for(int i=0;i<n;i++) visited[i]=false;
DFS(v,visited);
}
void BFS(int v){
bool* visited=new bool[n];
for(int i=0;i<n;i++)visited[i]=false;
cout<<v<<" ";
visited[v]=true;
queue<int> Q;
Q.push(v);
while(!Q.empty()){
v=Q.front();
Q.pop();
int w=getFirst(v);
while(w!=-1){
if(visited[w]==false){
cout<<w<<" ";
visited[w]=true;
Q.push(w);
}
w=getNext(v,w);
}
}
}
};
int main(){
int n,k;
cin>>n>>k;
Graph G(n);
int v1,v2;
for(int i=0;i<k;i++){
cin>>v1>>v2;
G.insertEdge(v1,v2);
}
G.DFS(0);
return 0;
}
问题 E: 无向图的广度优先搜索
题目描述
已知一个无向图G的顶点和边,顶点从0依次编号,现在需要广度优先搜索,访问任一邻接顶点时编号小的顶点优先,请编程输出图G的广度优先搜索序列。
输入
第一行是整数m和n(1
输出
该图从0号顶点开始的广度优先搜索序列。
样例输入
5 5
0 1
2 0
1 3
1 4
4 2
样例输出
0 1 2 3 4
#include
#include
using namespace std;
class Graph{
private:
int n;
int** edge;
public:
Graph(int n):n(n){
edge=new int*[n];
for(int i=0;i<n;i++){
edge[i]=new int[n];
for(int j=0;j<n;j++){
if(i==j)edge[i][j]=0;
else edge[i][j]=-1;
}
}
}
void insertEdge(int v1,int v2){
edge[v1][v2]=1;
edge[v2][v1]=1;
}
int getFirst(int v1){
for(int i=0;i<n;i++){
if(edge[v1][i]==1){
return i;
}
}
return -1;
}
int getNext(int v1,int v2){
for(int i=v2+1;i<n;i++){
if(edge[v1][i]==1){
return i;
}
}
return -1;
}
void DFS(int v,bool visited[]){
cout<<v<<" ";
visited[v]=true;
int w=getFirst(v);
while(w!=-1){
if(visited[w]==false)DFS(w,visited);
w=getNext(v,w);
}
}
void DFS(int v){
bool* visited=new bool[n];
for(int i=0;i<n;i++) visited[i]=false;
DFS(v,visited);
}
void BFS(int v){
bool* visited=new bool[n];
for(int i=0;i<n;i++)visited[i]=false;
cout<<v<<" ";
visited[v]=true;
queue<int> Q;
Q.push(v);
while(!Q.empty()){
v=Q.front();
Q.pop();
int w=getFirst(v);
while(w!=-1){
if(visited[w]==false){
cout<<w<<" ";
visited[w]=true;
Q.push(w);
}
w=getNext(v,w);
}
}
}
};
int main(){
int n,k;
cin>>n>>k;
Graph G(n);
int v1,v2;
for(int i=0;i<k;i++){
cin>>v1>>v2;
G.insertEdge(v1,v2);
}
G.BFS(0);
return 0;
}
问题 F: 最小生成树
题目描述
已知一个无向图G的顶点和边,顶点从0依次编号,请编程输出图G的最小生成树对应的边权之和。
输入
第一行是整数m和n(1
输出
最小生成树对应的边权之和。
样例输入
4 5
0 1 6
0 2 9
2 1 12
1 3 10
3 2 3
样例输出
18
#include
using namespace std;
#define Max 100000
class UFset{
private:
int* parent;
int size;
public:
UFset(int n):size(n){
parent=new int[size];
for(int i=0;i<size;i++)parent[i]=-1;
}
int Find(int x){
while(parent[x]>=0) x=parent[x];
return x;
}
void Union(int r1,int r2){
parent[r1]+=parent[r2];
parent[r2]=r1;
}
};
class Node{
public:
int v1,v2,value;
Node(int v1=-1,int v2=-1,int value=0){
v1=v1;
v2=v2;
value=value;
}
Node(const Node& n){
v1=n.v1;
v2=n.v2;
value=n.value;
}
};
class Graph{
private:
int n;
int* vertex;
int** edge;
void findMin(Node& newnode){
int x=0,y=1;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(edge[i][j]<edge[x][y]&&edge[i][j]!=0){
x=i;y=j;
}
}
}
newnode.v1=x;
newnode.v2=y;
newnode.value=edge[x][y];
edge[x][y]=Max;
edge[y][x]=Max;
}
public:
Graph(int n):n(n){
vertex=new int[n];
edge=new int*[n];
for(int i=0;i<n;i++){
vertex[i]=i;
edge[i]=new int[n];
for(int j=0;j<n;j++){
if(i==j)edge[i][j]=0;
else edge[i][j]=Max;
}
}
}
void insertEdge(int v1,int v2,int value){
edge[v1][v2]=value;
edge[v2][v1]=value;
}
void show(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<edge[i][j]<<" ";
}
cout<<endl;
}
}
int Kruskal(){
UFset F(n);
int count=0,sum=0;
int u,v;
Node newnode;
while(count<n-1){
findMin(newnode);
u=F.Find(newnode.v1);
v=F.Find(newnode.v2);
if(u!=v){
F.Union(u,v);
sum+=newnode.value;
count++;
}
}
return sum;
}
};
int main(){
int n,k;
cin>>n>>k;
Graph G(n);
int v1,v2,value;
for(int i=0;i<k;i++){
cin>>v1>>v2>>value;
G.insertEdge(v1,v2,value);
}
int min=G.Kruskal();
cout<<min<<endl;
return 0;
}