树的建立以及遍历、深度、叶子节点

               **树的建立**

1.已知先序遍历,建立二叉树。
模板:

char a[100];
int i;
struct node * creat(struct node * root)
{
   if(a[++i]==',')
    root = NULL;
   else
   {
      root = (struct node *)malloc(sizeof(struct node));
      root->data = a[i];
      root->left = creat(root->left);
      root->right = creat(root->right);
   }
   return root;
}

例题:

   数据结构实验之二叉树二:遍历二叉树

Time Limit: 1000MS Memory Limit: 65536KB
Problem Description

已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点)。请建立二叉树并按中序和后序的方式遍历该二叉树。
Input

连续输入多组数据,每组数据输入一个长度小于50个字符的字符串。
Output

每组输入数据对应输出2行:
第1行输出中序遍历序列;
第2行输出后序遍历序列。

Example Input

abc,,de,g,,f,,,

Example Output

cbegdfa
cgefdba

Hint

Author
xam

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
  char data;
  struct node * right;
  struct node * left;
};
char a[100];
int i;
struct node * creat(struct node * root)
{
   if(a[++i]==',')
    root = NULL;
   else
   {
      root = (struct node *)malloc(sizeof(struct node));
      root->data = a[i];
      root->left = creat(root->left);
      root->right = creat(root->right);
   }
   return root;
}
void postorder(struct node * root)
{
    if(root)
    {
       postorder(root->left);
       postorder(root->right);
       printf("%c", root->data);
    }
}
void inorder(struct node * root)
{
    if(root)
    {
       inorder(root->left);
       printf("%c", root->data);
       inorder(root->right);
    }
}
int main()
{
    while(~scanf("%s", a))
    {
      struct node * root;
      root = (struct node *)malloc(sizeof(struct node));\
      i = -1;
      root = creat(root);
      inorder(root);
      printf("\n");
      postorder(root);
      printf("\n");
    }
    return 0;
}

2.已知先序遍历和中序遍历,建立二叉树。
模板:

char mid[100002], pre[100003];
struct node * creat(int prel, int prer, int midl, int midr)
{
   if(prer<prel)
   return NULL;
   struct node * root;
   root = (struct node *)malloc(sizeof(struct node));
   root->data = pre[prel];
   if(prer==prel)
   {
      root->data = pre[prel];//前序遍历的第一个数为根节点
      root->left = NULL;
      root->right = NULL;
      return root;
   }
   int index;//记录中序里面根节点的位置
   for(index=midl;index<=midr;index++)
   {
     if(mid[index]==pre[prel])
     break;//在中序遍历里面找到根节点的位置
   }
   root->left = creat(prel+1, index-midl+prel, midl, index-1);
   root->right = creat(index-midl+prel+1, prer, index+1, midr);
   return root;
}

例题:
数据结构上机测试4.1:二叉树的遍历与应用1
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
输入二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列。
Input
第一行输入二叉树的先序遍历序列;
第二行输入二叉树的中序遍历序列。
Output
输出该二叉树的后序遍历序列。
Example Input

ABDCEF
BDAECF

Example Output

DBEFCA

Hint
Author
代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
  char data;
  struct node * right;
  struct node * left;
};
char mid[100002], pre[100003];
struct node * creat(int prel, int prer, int midl, int midr)
{
   if(prer<prel)
   return NULL;
   struct node * root;
   root = (struct node *)malloc(sizeof(struct node));
   root->data = pre[prel];
   if(prer==prel)
   {
      root->data = pre[prel];//前序遍历的第一个数为根节点
      root->left = NULL;
      root->right = NULL;
      return root;
   }
   int index;//记录中序里面根节点的位置
   for(index=midl;index<=midr;index++)
   {
     if(mid[index]==pre[prel])
     break;//在中序遍历里面找到根节点的位置
   }
   root->left = creat(prel+1, index-midl+prel, midl, index-1);
   root->right = creat(index-midl+prel+1, prer, index+1, midr);
   return root;
}
void postorder(struct node * root)
{
    if(root)
    {
       postorder(root->left);
       postorder(root->right);
       printf("%c", root->data);
    }
}
void inorder(struct node * root)
{
    if(root)
    {
       inorder(root->left);
       printf("%c", root->data);
       inorder(root->right);
    }
}
int main()
{
  struct node * root;
  root = (struct node *)malloc(sizeof(struct node));
  scanf("%s", pre);
  scanf("%s", mid);
  root = creat(0, strlen(pre)-1, 0, strlen(mid)-1);
  postorder(root);
  printf("\n");
    return 0;
}

3.已知中序遍历和后序遍历,建立二叉树。
模板:

char mid[100002], post[100003];
struct node * creat(int postl, int postr, int midl, int midr)
{
    if(postl>postr)
    return NULL;
    struct node * root;
    root = (struct node *)malloc(sizeof(struct node));
    root->data = post[postr];//后序遍历的最后一个数字是根节点
    if(postr==postl)
    {
       root->left = NULL;
       root->right = NULL;
       return root;
    }
    int index;
    for(index=midl;index<=midr;index++)
    {
      if(mid[index]==post[postr])//在中序遍历中找到根节点的位置
      break;
    }
    root->left = creat(postl, index-midl+postl-1, midl, index-1);
    root->right = creat(index-midl+postl, postr-1, index+1, midr);
    return root;
}

例题:
求二叉树的先序遍历
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历
Input
输入数据有多组,第一行是一个整数t (t<1000),代表有t组测试数据。每组包括两个长度小于50 的字符串,第一个字符串表示二叉树的中序遍历序列,第二个字符串表示二叉树的后序遍历序列。
Output
输出二叉树的先序遍历序列
Example Input

2
dbgeafc
dgebfca
lnixu
linux

Example Output

abdegcf
xnliu

Hint

Author
GYX
代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
  char data;
  struct node * right;
  struct node * left;
};
char mid[100002], post[100003];
struct node * creat(int postl, int postr, int midl, int midr)
{
    if(postl>postr)
    return NULL;
    struct node * root;
    root = (struct node *)malloc(sizeof(struct node));
    root->data = post[postr];//后序遍历的最后一个数字是根节点
    if(postr==postl)
    {
       root->left = NULL;
       root->right = NULL;
       return root;
    }
    int index;
    for(index=midl;index<=midr;index++)
    {
      if(mid[index]==post[postr])//在中序遍历中找到根节点的位置
      break;
    }
    root->left = creat(postl, index-midl+postl-1, midl, index-1);
    root->right = creat(index-midl+postl, postr-1, index+1, midr);
    return root;
}
void preorder(struct node * root)
{
    if(root)
    {
       printf("%c", root->data);
       preorder(root->left);
       preorder(root->right);
    }
}
int main()
{
 int n;
 scanf("%d", &n);
 while(n--)
 {
  struct node * root;
  root = (struct node *)malloc(sizeof(struct node));
   scanf("%s", mid);
   scanf("%s", post);
   root = creat(0, strlen(mid)-1, 0, strlen(post)-1);
    preorder(root);
  printf("\n");
 }
    return 0;
}
        **树的遍历**

1.树的先序遍历。
模板:

void preorder(struct node * root)
{
    if(root)
    {
       printf("%c", root->data);
       preorder(root->left);
       preorder(root->right);
    }
}

2.树的中序遍历。
模板:

void midorder(struct node * root)
{
   if(root)
   {
      midorder(root->left);
      printf("%c", root->data);
      midorder(root->right);
   }
}

3.树的后序遍历。
模板:

void postorder(struct node * root)
{
    if(root)
    {
       postorder(root->left);
       postorder(root->right);
       printf("%c", root->data);
    }
}

4.树的层序遍历。
模板:

void level(struct node * root)
{
   struct node * p;
   struct node * queue[2000];
   int front = 0, rear = 0;
   if(root)
   {
      queue[rear++] = root;
      while(front!=rear)
      {
         p = queue[front++];
         printf("%c", p->data);
         if(p->left)
         queue[rear++] = p->left;
         if(p->right)
         queue[rear++] = p->right;
      }
   }
}

例题:
数据结构实验之二叉树五:层序遍历
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description

已知一个按先序输入的字符序列,如abd,,eg,,,cf,,,(其中,表示空结点)。请建立二叉树并求二叉树的层次遍历序列。
Input
输入数据有多行,第一行是一个整数t (t<1000),代表有t行测试数据。每行是一个长度小于50个字符的字符串。
Output
输出二叉树的层次遍历序列。
Example Input

2
abd,,eg,,,cf,,,
xnl,,i,,u,,

Example Output

abcdefg
xnuli

Hint

Author
xam
代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
   char data;
   struct node * left, *right;
};
char a[60];
int i;
struct node * creat(struct node *root)
{
    if(a[++i]==',')
    root = NULL;
    else
    {
      root = (struct node *)malloc(sizeof(struct node));
      root->data = a[i];
      root->left = creat(root->left);
      root->right = creat(root->right);
    }
    return root;
}
void level(struct node * root)
{
   struct node * p;
   struct node * queue[2000];
   int front = 0, rear = 0;
   if(root)
   {
      queue[rear++] = root;
      while(front!=rear)
      {
         p = queue[front++];
         printf("%c", p->data);
         if(p->left)
         queue[rear++] = p->left;
         if(p->right)
         queue[rear++] = p->right;
      }
   }
}
int main()
{
   int t;
   struct node * root;
   root = (struct node *)malloc(sizeof(struct node));
   scanf("%d", &t);
   getchar();
   while(t--)
   {
     i = -1;
    scanf("%s", a);
    root = creat(root);
    level(root);
    printf("\n");
    }
    return 0;
}

统计树的叶子节点数
模板:

int count(struct node * root)
{
   int m = 0;
   if(root==NULL)
   return 0;
   else if(root->right==NULL&&root->left==NULL)
   return 1;
     m += count(root->left) + count(root->right);
     return m;
}

例题:
数据结构实验之二叉树三:统计叶子数
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description

已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点)。请建立二叉树并求二叉树的叶子结点个数。
Input

连续输入多组数据,每组数据输入一个长度小于50个字符的字符串。
Output

输出二叉树的叶子结点个数。
Example Input

abc,,de,g,,f,,,

Example Output

3

Hint

Author
代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
   char data;
   struct node * left, *right;
};
char a[60];
int i;
struct node * creat(struct node *root)
{
    if(a[++i]==',')
    root = NULL;
    else
    {
      root = (struct node *)malloc(sizeof(struct node));
      root->data = a[i];
      root->left = creat(root->left);
      root->right = creat(root->right);
    }
    return root;
}
int count(struct node * root)
{
   int m = 0;
   if(root==NULL)
   return 0;
   else if(root->right==NULL&&root->left==NULL)
   return 1;
     m += count(root->left) + count(root->right);
     return m;
}
int main()
{
   struct node * root;
   root = (struct node *)malloc(sizeof(struct node));
    while(~scanf("%s", a))
    {
    i = -1;
    root = creat(root);
   printf("%d\n", count(root));
   }
    return 0;
}

树的高度
模板:

int high(struct node * root)
{
    int lh, rh, h;
    if(!root)
    h =  0;
    else
    {
       lh = high(root->left);
       rh = high(root->right);
       if(lh>=rh)
       h = lh + 1;
       else
       h = rh + 1;
    }
    return h;
}

例题:

数据结构实验之二叉树四:还原二叉树
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description

给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。
Input
输入数据有多组,每组数据第一行输入1个正整数N(1 <= N <= 50)为树中结点总数,随后2行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区分大小写)的字符串。

Output
输出一个整数,即该二叉树的高度。
Example Input

9
ABDFGHIEC
FDHGIBEAC

Example Output

5

Hint

Author
xam

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
   char data;
   struct node * left, *right;
};
char pre[3000], mid[3000];
struct node * creat2(int prel, int prer, int midl, int midr)
{
   struct node * root;
   root = (struct node *)malloc(sizeof(struct node));
   if(prel>prer)
   return NULL;
   root->data = pre[prel];
   if(prel==prer)
   {
     root->left = NULL;
     root->right = NULL;
     return root;
   }
   int index;
   for(index=midl;index<=midr;index++)
   {
      if(mid[index]==pre[prel])
      break;
   }
   root->left = creat2(prel+1, prel+(index-midl), midl, index-1);
   root->right = creat2(prel+(index-midl)+1, prer, index+1, midr);
   return root;
}
int high(struct node * root)
{
    int lh, rh, h;
    if(!root)
    h =  0;
    else
    {
       lh = high(root->left);
       rh = high(root->right);
       if(lh>=rh)
       h = lh + 1;
       else
       h = rh + 1;
    }
    return h;
}
int main()
{
   struct node * root;
   root = (struct node *)malloc(sizeof(struct node));
   int t;
   while(~scanf("%d", &t))
    {
    scanf("%s", pre);
    scanf("%s", mid);
    root = creat2(0, t-1, 0, t-1);
   printf("%d\n", high(root));
   }
    return 0;
}

树的同构
数据结构实验之二叉树一:树的同构
代码实现:
(可能不是很好懂,先试着看看,以后再写个好理解的)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
 char data;
 int lc,rc;
}a[100];
int num=0;
struct node1
{
 char data1;
 struct node1 *l,*r;
}*T1, *T2;
int v[100];
struct node1 *creat(struct node1 *root,int k)
{

 root=(struct node1 *)malloc(sizeof(struct node1));
 root->l=NULL;
 root->r=NULL;
 root->data1=a[k].data;
 if(a[k].lc!=-1)root->l=creat(root->l,a[k].lc);
 if(a[k].rc!=-1)root->r=creat(root->r,a[k].rc);
 return root;
}
int judge(struct node1 *T1,struct node1 *T2)
{
 if((!T1)&&(!T2))return 1;
 else if(T1&&T2)
 {
  if(T1->data1==T2->data1)
  {
   num++;
   if((judge(T1->l,T2->l)&&judge(T1->r,T2->r))||(judge(T1->l,T2->r)&&judge(T1->r,T2->l)))
   {
    return 1;
   }
  }
 }
  return 0;
}
int main()
{
 int n,m;
 int i;
 char s1[10],s2[10],s3[10];
 while(scanf("%d",&n)!=EOF)
 {
  memset(v,0,sizeof(v));
  for(i=0;i<n;i++)
  {
   scanf("%s%s%s",&s1,&s2,&s3);
   a[i].data=s1[0];
   if(s2[0]=='-')
    a[i].lc=-1;
   else
   {
    a[i].lc=s2[0]-'0';
    v[a[i].lc]=1;
   }
   if(s3[0]=='-')
    a[i].rc=-1;
   else
   {
    a[i].rc=s3[0]-'0';
    v[a[i].rc]=1;
   }
  }
  int flag;
  if(n!=0)
  {
   int j;
   for(j=0;j<n;j++)
   {
    if(!v[j])break;
   }
   T1=creat(T1,j);
  }
  scanf("%d",&m);
  memset(v,0,sizeof(v));
  for(i=0;i<m;i++)
  {
   scanf("%s %s %s",&s1, &s2, &s3);
   a[i].data=s1[0];
   if(s2[0]=='-')
    a[i].lc=-1;
   else
   {
    a[i].lc=s2[0]-'0';
    v[a[i].lc]=1;
   }
   if(s3[0]=='-')
    a[i].rc=-1;
   else
   {
    a[i].rc=s3[0]-'0';
    v[a[i].rc]=1;
   }
  }
  int j=0;
  for(;j<m;j++)
   if(!v[j])break;
   T2=creat(T2,j);
   num=0;
   judge(T1,T2);
   if(num==n)printf("Yes\n");
   else printf("No\n");
 }
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值