根据先序和中序(中序和后序)确定二叉树

实在是恨自己智商欠费,一个二叉树搞了好长时间才弄清!!!
怎样通过先序和中序确定二叉树?
我的算法设计思路参考学习网上的,但代码是自己实现的,其实还是在创建二叉树的基础上添加一些条件。我们刚开始根据先序序列中第一个数据,在中序序列中找与该结点数据相等的与元素,将中序序列中该元素所在下标返回。创建节点,将先序序列的第一个有效元素存起来。将中序序列中与前序序列当前第一个元素相等的元素所在位置置为’\0’,并将前序序列中的该元素所在位置值置为’\0’,先序序列的首个有效元素也同时应改为下一个元素(即此时遍历下标应后移)。这是建立二叉树之前所做的工作。
创建二叉树还是用递归,根据以上返回的下标将中序序列分为两部分,判断左边为空,就将创建节点的左孩子置为空,右边同理。
若不为空,前半部分为左子树,后半部分为右子树。
将前序序列和中序序列前半部分,以及创建的结点的左孩子指针传进去。递归调用函数。
将前序序列和中序序列后半部分,以及创建的结点的右孩子指针传进去。递归调用函数。
以上所述为火星人理解思路,看不懂不怪你们,怪我,表达上确实欠缺逻辑性,下面我们看代码就行~~~

#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;
typedef struct node{
    
    char ch ;
    struct node * l,*r ;
}node_t,*node_l;

void create_tree(node_l * root,char  prelist[],char  midlist[]);
int findIndex(char prelist,char* midlist);
void print(node_l root);
int main(){
    
    node_l root ;
    char prelist[100];
    char midlist[100];
    bzero(prelist,sizeof(prelist));
    bzero(midlist,sizeof(midlist));
    cin>>prelist;
    cin>>midlist;
    create_tree(&root,prelist,midlist);
    print(root);
}
void print(node_l root){

    if(root){
        print(root->l);
        print(root->r);
        cout<<root->ch<<"";
    }
}
//该函数时恢复二叉树的,root为根指,prelist为先序序列,midlist为中序序列
//三者在恢复二叉树的过程中时变化的
void create_tree(node_l* root,char prelist[],char midlist[]){
    //定义静态变量,因为每次前序每一个元素,就销毁一个元素,
    //下标也作相应的移动。
    static int index = 0;  
    int mid_index ;
    //传入前序序列的首元素,在中序列中搜索  ,记录元素在中序序列中所处的下标  
    mid_index = findIndex(prelist[index],midlist);
    *root = (node_l)malloc(sizeof(node_t));
    //将节点数据存在根结点中
    (*root)->ch = prelist[index];
    将先序已遍历的数据全置为‘\0’
    prelist[index++]='\0' ;
    //将中序的那个数据所处位置置为'\0'
    midlist[mid_index]='\0';
    //判断那个位置之前是否为空,若非空,说明当前节点有左子树,继续递归创建左子树
    if(midlist[mid_index-1]!='\0'){
        create_tree(&((*root)->l),prelist,midlist);
    }
    //否则的话就将当前节点的左孩子置为空
    else{
        (*root)->l = NULL ;
    }
    //若当前节点有右孩子,递归创建
    if(midlist[mid_index+1]!='\0'){
        create_tree(&((*root)->r),prelist,&midlist[mid_index+1]);
    }
    else{
        (*root)->r = NULL ;
    }
}
//根据传进来的中序首元素节点,在中序序列中找该结点下标。
int findIndex(char  pre,char * mid){   
    int i ;
    for(i = 0; *(mid+i)!= '\0' ;i++){
        if(pre == *(mid+i)){
            return i ;
        }
    }
    return 0;
}

根据后序和中序创建二叉树时同样的道理,自己在这个基础上尝试找一些规律,就可以自己恢复了。
后序和中序

#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;
typedef struct node{
    
    char ch ;
    struct node * l,*r ;
}node_t,*node_l;

void create_tree(node_l * root,char  lastlist[],char  midlist[]);
int findIndex(char last,char* midlist);
void print(node_l root);
int main(){
    
    node_l root ;
    char lastlist[100];
    char midlist[100];
    bzero(lastlist,sizeof(lastlist));
    bzero(midlist,sizeof(midlist));
    cin>>midlist;
    cin>>lastlist;
    create_tree(&root,lastlist,midlist);
    print(root);
}
void print(node_l root){

    if(root){
        cout<<root->ch<<"";
        print(root->l);
        print(root->r);
    }
}
void create_tree(node_l* root,char lastlist[],char midlist[]){
    static int index = strlen(lastlist)-1;
    int mid_index ;    
    
    mid_index = findIndex(lastlist[index],midlist);
    *root = (node_l)malloc(sizeof(node_t));
    (*root)->ch = lastlist[index];

    lastlist[index--]='\0' ;
    if(index==-1)return ;
    midlist[mid_index]='\0';
    if(midlist[mid_index+1]!='\0'){
        create_tree(&((*root)->r),lastlist,&midlist[mid_index+1]);
    }
    else{
        (*root)->r = NULL ;
    }
    if(midlist[mid_index-1]!='\0'){
        create_tree(&((*root)->l),lastlist,midlist);
    }
    else{
        (*root)->l = NULL ;
    }
}

int findIndex(char  last,char * mid){
    
    int i ;
    for(i = 0; *(mid+i)!= '\0' ;i++){
        if(last == *(mid+i)){
            return i ;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41681241/article/details/83859974