基础搜索
二叉树的深度与宽度
题目描述 Description
给出一个二叉树,输出它的最大宽度和高度。
输入描述 Input Description
第一行一个整数n。
下面n行每行有两个数,对于第i行的两个数,代表编号为i的节点所连接的两个左右儿子的编号。如果没有某个儿子为空,则为0。
输出描述 Output Description
输出共一行,输出二叉树的最大宽度和高度,用一个空格隔开。
样例输入 Sample Input
5
2 3
4 5
0 0
0 0
0 0
样例输出 Sample Output
2 3
#include<iostream>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string.h>
#include<string>
#include<stdio.h>
using namespace std;
#define maxn 16
int **tree;
int num;
int *wide;
int *dep;
int dfs(int k)
{
if(k==0)
return 0;
int left=dfs(tree[k][0])+1;
int right=dfs(tree[k][1])+1;
return left>right?left:right;
}
void dfs(int m,int deep)
{
if(m==0)
return ;
if (wide[m]==0)
{
dep[deep]++;
wide[m]=1;
}
dfs(tree[m][0],deep+1);
dfs(tree[m][1],deep+1);
}
int main()
{
cin>>num;
tree=new int *[17];
wide=new int[num+1];
for(int i=0;i<num+1;i++)
{
wide[i]=0;
}
for(int i=0;i<17;i++)
{
tree[i]=new int[2];
}
for(int i=1;i<=num;i++)
{
cin>>tree[i][0];
cin>>tree[i][1];
}
int deep=dfs(1);
dep=new int[deep];
for(int i=0;i<deep;i++)
{
dep[i]=0;
}
dfs(1,0);
sort(dep,dep+deep);
cout<<dep[deep-1]<<" "<<deep<<endl;
return 0;
}
二叉树的序遍历
题目描述 Description
求一棵二叉树的前序遍历,中序遍历和后序遍历
输入描述 Input Description
第一行一个整数n,表示这棵树的节点个数。
接下来n行每行2个整数L和R。第i行的两个整数Li和Ri代表编号为i的节点的左儿子编号和右儿子编号。
输出描述 Output Description
输出一共三行,分别为前序遍历,中序遍历和后序遍历。编号之间用空格隔开。
样例输入 Sample Input
5
2 3
4 5
0 0
0 0
0 0
样例输出 Sample Output
1 2 4 5 3
4 2 5 1 3
4 5 2 3 1
#include<iostream>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string.h>
#include<string>
#include<stdio.h>
using namespace std;
#define maxn 17
int tree[maxn][2];
void dfs(int n)
{
if(n==0)
{
return;
}
cout<<n<<" ";
dfs(tree[n][0]);
dfs(tree[n][1]);
}
void dfs1(int n)
{
if(n==0)
{
return;
}
dfs1(tree[n][0]);
cout<<n<<" ";
dfs1(tree[n][1]);
}
void dfs2(int n)
{
if(n==0)
{
return;
}
dfs2(tree[n][0]);
dfs2(tree[n][1]);
cout<<n<<" ";
}
int main()
{
int num;
cin>>num;
for(int i=1;i<=num;i++)
{
cin>>tree[i][0];
cin>>tree[i][1];
}
dfs(1);
cout<<endl;
dfs1(1);
cout<<endl;
dfs2(1);
return 0;
}
典型hanio问题
汉诺塔问题(又称为河内塔问题),是一个大家熟知的问题。在A,B,C三根柱子上,有n个不同大小的圆盘(假设半径分别为1-n吧),一开始他们都叠在我A上(如图所示),你的目标是在最少的合法移动步数内将所有盘子从A塔移动到C塔。
游戏中的每一步规则如下:
-
每一步只允许移动一个盘子(从一根柱子最上方到另一个柱子的最上方)
-
移动的过程中,你必须保证大的盘子不能在小的盘子上方(小的可以放在大的上面,最大盘子下面不能有任何其他大小的盘子)
如对于n=3的情况,一个合法的移动序列式:
1 from A to C
2 from A to B
1 from C to B
3 from A to C
1 from B to A
2 from B to C
1 from A to C
给出一个数n,求出最少步数的移动序列
输入描述 Input Description
一个整数n
输出描述 Output Description
第一行一个整数k,代表是最少的移动步数。
接下来k行,每行一句话,N from X to Y,表示把N号盘从X柱移动到Y柱。X,Y属于{A,B,C}
样例输入 Sample Input
3
样例输出 Sample Output
7
1 from A to C
2 from A to B
1 from C to B
3 from A to C
1 from B to A
2 from B to C
1 from A to C
#include<iostream>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string.h>
#include<string>
#include<stdio.h>
using namespace std;
int num;
void hanio(char a,char b,char c,int n)
{
if(n==1)
{
//num=a-'A'+1;
//num++;
cout<<n<<" from "<<a<<" to "<</*b*/c<<endl;
//cout<<++num<<" from "<<a<<" to "<<c<<endl;
//cout<<++num<<" from "<<b<<" to "<<c<<endl;
}
else
{
hanio(a,c,b,n-1);
//num=a-'A'+1;
//num++;
cout<<n<<" from "<<a<<" to "<</*b*/c<<endl;
//hanio(a,b,c,n-1);
hanio(b,a,c,n-1);
}
}
void hanionum(char a,char b,char c,int n)
{
if(n==1)
{
//num=a-'A'+1;
num++;
//cout<<n<<" from "<<a<<" to "<</*b*/c<<endl;
//cout<<++num<<" from "<<a<<" to "<<c<<endl;
//cout<<++num<<" from "<<b<<" to "<<c<<endl;
}
else
{
hanionum(a,c,b,n-1);
//num=a-'A'+1;
num++;
//cout<<n<<" from "<<a<<" to "<</*b*/c<<endl;
//hanio(a,b,c,n-1);
hanionum(b,a,c,n-1);
}
}
int main()
{
int n;
cin>>n;
hanionum('A','B','C',n);
cout<<num<<endl;
hanio('A','B','C',n);
return 0;
}