算法(五) 树
1.树
题2029
题目描述
K城这里有很多棵树,树的大小和形状不尽相同。
下面小A想指着一个节点,问一问你这个树的规模是多大(这棵树有几个节点)
对于每个节点而言,其不会有超过5个子节点。
输入
第一行是一个数字n(n<=2000),表示树的节点数。
接下来n行,每行是两个数fi,si(保证si仅包含一个父亲节点) 表示si的父亲是fi,如果是si是根节点,则fi=0
接下来一个数k,表示小A指着的节点。
输出
一个数,表示树的规模。
样例输入
6
2 5
1 3
2 1
0 2
6 4
0 6
4
样例输出
2
#include<iostream>
#include<cstdio>
using namespace std;
int n=0,ans;
struct node
{
int child[6],n,father;
//child表示当前节点的子节点,
//n表示当前结点子节点个数,
//father表示当前节点的父节点
};
node tree[10086];
int findroot(int x) //寻找根节点
{
if(tree[x].father==0)
return x;
else
return findroot(tree[x].father);
}
void f(int t) //计算当前节点下方的所有节点
{
ans++; //统计个数
int x;
for(x=1;x<=tree[t].n;x++) //当树遍历到最后一层,n=0,循环结束
f(tree[t].child[x]);
}
int main()
{
int z;
cin>>z;
int i,si,fi,j;
for(i=1;i<=z;i++) //建立树结构
{
cin>>fi>>si;
tree[si].father=fi;
if(fi!=0)
{
for(j=1;j<=5;j++)
{
if(tree[fi].child[j]==0)
{
tree[fi].child[j]=si;
tree[fi].n++;
break;
}
}
}
}
int k;
ans=0;
cin>>k;
f(findroot(k));
cout<<ans;
}
2.二叉树
二叉树是每个父节点最多只有两个子节点
二叉树结构体
typedef int Elementtype;
typedef struct TreeNode{
Elementtype data;
TreeNode* left;
TreeNode* right;
}TreeNode,*PTREE;
构建二叉树
//输入 abcdefg*** 建立先序遍历为abcdefg的普通树
//需要修改指向 树结构的 指针,所以形参为 指针的引用(指针的指针)
void CreatTree(PTREE& Root){
char a=0;
a = getchar();
if(a==’’){
Root = NULL;
}
else{
Root = (TreeNode *)malloc(sizeof(TreeNode));
if(Root==NULL)
printf(“Failed”);
else{
Root->data = a;
CreatTree(Root->left);
CreatTree(Root->right);
}
}
}
二叉树的遍历分为 先序 中序 后序遍历
先序:到达一个节点后,即刻输出该节点的值,并继续遍历其左右子树。 VLR
中序:到达一个节点后,将其暂存,遍历完左子树后,再输出该节点的值,然后遍历右子树 LVR
后序:到达一个节点后,将其暂存,遍历完左右子树后,再输出该节点的值 LRV
//先序**
void fsearch(PTREE Root){
if (Root == NULL) return;
else{
printf("%d ",Root->data);
fsearch(Root->left);
fsearch(Root->right);
}
}
// 中序
void msearch(PTREE Root){
if (Root == NULL) return;
else{
msearch(Root->left);
printf("%d ",Root->data);
msearch(Root->right);
}
}
// 后序
void psearch(PTREE Root){
if (Root == NULL) return;
else{
psearch(Root->left);
psearch(Root->right);
printf("%d ",Root->data);
}
}
题2030
题目描述
对于一棵二叉树,请输出它的中序遍历。
输入
第一行包括一个数n(n<=2000),表示节点的个数。
接下来n行,每行两个数li,ri,表示i节点的左子节点和右子节点。0表示为空
输出
输出一行,共n个数,表示中序遍历。
样例输入
6
2 3
4 0
5 6
0 0
0 0
0 0
样例输出
4 2 1 5 3 6
#include<iostream>
#include<cstdio>
using namespace std;
struct node //整个二叉树由一个个小的node组成,每个小node包括自己,左下节点与右下节点
{
int data;
int left;
int right;
}node[3000];
void output(int root) //中序输出
{
if(root!=0)
{
if(node[root].left!=0)
output(node[root].left);
cout<<node[root].data<<" ";
if(node[root].right!=0)
output(node[root].right);
}
}
int main()
{
int n,i,l,r;
cin>>n;
node[1].data=1;
for(i=1;i<=n;i++) //二叉树的输入与构建
{
cin>>l>>r;
if(l!=0)
{
node[i].left=l;
node[l].data=l;
}
else
node[i].left=0;
if(r!=0)
{
node[i].right=r;
node[r].data=r;
}
else
node[i].right=0;
}
//输出
output(1);
cout<<endl;
return 0;
}