zoukankan      html  css  js  c++  java
  • 由二叉树的先序中序推出后序(转)

    三序中知道其中两个就可以推出第三个,但前提是我们必须知道中序.因为:

    先序和后序给我们提供的信息是一样的--告诉我们谁是根节点

    中序则告诉我们左右子树在哪儿

    例:已知先序为eacbdgf,中序为abcdefg,求后序

    由先序我们知道e为根节点,我们在中序中把左右子树括起来 --(abcd)e(fg)

    同样对左子树abcd进行分析,先序为acbd,中序为abcd.--a(bcd)

    递归下去就可以了

    后序为bdcafge

    代码实现上述例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #include "stdio.h"
    #include "string.h"
    #include "stdlib.h"
     
    //定义二叉树的节点
    typedef  struct  node{
         char  data;
         struct  node* left;
         struct  node* right;
    }NODE;
    //后根遍历打印二叉树
    void  postTrav(NODE* root){
         //遍历左子树
         if (root->left!=NULL)
             postTrav(root->left);
         //遍历右子树
         if (root->right!=NULL)
             postTrav(root->right);
         //输出本节点
         printf ( "%c" ,root->data);
    }
    //根据前序和中序建立二叉树
    void  buildTree( char * pre, char * mid,NODE* root){
         int  len= strlen (pre);        //实际下先序序列和后序序列的长度是一样的
         //序列长度为0,说明上一级已经是叶子节点,返回
         if (len==0)
             return ;
         
         //返回先序的第一个元素在中序中出现的位置
         char * p= strchr (mid,pre[0]);
         int  pos=( int )(p-mid);
         
         //建设子树的根节点
         //先序中第一个元素作为本子树的根节点
         root->data=pre[0];
         
         if (pos!=0){         //当前节点的左子树是存在的
             NODE* left=(NODE*) malloc ( sizeof ( struct  node));
             root->left=left;
             //左子树根节点上的元素就是先序中的第2个元素
             left->data=pre[1];  
             char * left_pre=( char *) malloc (pos* sizeof ( char ));
             char * left_mid=( char *) malloc (pos* sizeof ( char ));
             //找到左子树的先序和中序
             strncpy (left_pre,pre+1,pos);
             strncpy (left_mid,mid,pos);
             //递归建立左子树
             buildTree(left_pre,left_mid,left);
         }
     
         if (pos!=len-1){     //当前节点的右子树是存在的
             NODE* right=(NODE*) malloc ( sizeof ( struct  node));
             root->right=right;
             //右子树根节点上的元素就是先序中的第pos+2个元素
             right->data=pre[pos+1];
             char * right_pre=( char *) malloc ((len-1-pos)* sizeof ( char ));
             char * right_mid=( char *) malloc ((len-1-pos)* sizeof ( char ));
             //找到右子树的先序和中序
             strncpy (right_pre,pre+pos+1,len-1-pos);
             strncpy (right_mid,mid+pos+1,len-1-pos);
             //递归建立右子树
             buildTree(right_pre,right_mid,right);
         }
    }
    //主函数
    int  main(){
         printf ( "input number of elements: " );
         int  size=0;
         scanf ( "%d" ,&size);
         char * pre=( char *) malloc (size* sizeof ( char ));
         char * mid=( char *) malloc (size* sizeof ( char ));
         printf ( "input preorder: " );
         scanf ( "%s" ,pre);
         printf ( "input midorder: " );
         scanf ( "%s" ,mid);
         NODE* root=(NODE*) malloc ( sizeof ( struct  node));
         buildTree(pre,mid,root);
         printf ( "the postorder is: " );
         postTrav(root);
         printf ( " " );
         return  0;
    }

    这里顺便再介绍几个C语言里面的函数

    首先对于指针变量必须先初始化malloc后才能使用,比如在上面的main函数中你没有char* pre=(char*)malloc(size*sizeof(char));就来个scanf("%s",pre);会发生段错误.

    第1个函数:

    表头文件#include<string.h>

    定义函数char * strchr (const char *s,int c);

    函数说明strchr()用来找出参数s字符串中第一个出现的参数c地址,然后将该字符出现的地址返回。

    返回值如果找到指定的字符则返回该字符所在地址,否则返回0。

    #include<string.h>

    main()

    {

    char *s="0123456789012345678901234567890";

    char *p;p=strchr(s,'5');

    printf("%d ",p-s);

    }

    第2个函数:

    表头文件#include <string.h>

    定义函数char *strpbrk(const char *s,const char *accept);

    函数说明strpbrk()用来找出参数s 字符串中最先出现存在参数accept 字符串中的任意字符。

    返回值如果找到指定的字符则返回该字符所在地址,否则返回0。

    #include <string.h>

    main()

    {

    char *s="0123456789012345678901234567890";

    char *p;

    p=strpbrk(s,"a1 839"); /*1会最先在s字符串中找到*/

    printf("%d ",(p-s));

    p=strpbrk(s,"4398");/*3 会最先在s 字符串中找到*/

    printf("%d ",(p-s));

    }

    第3个函数:

    表头文件#include<string.h>

    定义函数char * strncpy(char *dest,const char *src,size_t n);

    函数说明strncpy()会将参数src字符串拷贝前n个字符至参数dest所指的地址。

    前提是dest必须能够容纳下n个字符.

    返回值返回参数dest的字符串起始地址。

    #inclue <string.h>

    main()

    {

    char a[30]="string(1)";

    char b[]="string(2)";

    printf("before strncpy() : %s ",a);

    printf("after strncpy() : %s ",strncpy(a,b,6));

    }

    C语言里面没有substr这样的函数,截取子串的功能就是通过strncpy来实现的,比如在我们的代码中有:

    strncpy(left_pre,pre+1,pos);

    这就是从pre的第2个元素开始,截取pos个字符放到left_pre中

    原文来自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun
  • 相关阅读:
    hdu1085
    hdu1028
    hdu2189
    母函数
    博弈论
    nginx安装
    学习好站点
    nginx在linux下安装
    wget 命令用法详解
    U盘安装CentOS7的帖子
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3275402.html
Copyright © 2011-2022 走看看