二叉树——根据二叉树遍历序列构造二叉树

来源:互联网 发布:淘宝最热门关键词 编辑:程序博客网 时间:2024/06/05 03:47

根据前序序列和中序序列构造二叉树

  二叉树的节点类型声明如下:

struct BTNode {    char val;    BTNode *left;    BTNode *right;    BTNode(char c):val(c), left(NULL), right(NULL);};

定理1 任何(n>=0)个不同节点的二叉树,都可由它的前序序列和中序序列唯一地确定。
  根据前序遍历的特点, 知前序序列(PreSequence)的首个元素(PreSequence[0])为二叉树的根(root), 然后在中序序列(InSequence)中查找此根(root), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为根的左子树的中序遍历序列, 后边的序列为根的右子树的中序遍历序列。 设在中序遍历序列(InSequence)根前边有left个元素. 则在前序序列(PreSequence)中, 紧跟着根(root)的left个元素序列(即PreSequence[1…left]) 为根的左子树的前序遍历序列, 在后边的为根的右子树的前序遍历序列.而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为PreSequence[1…left]), 中序序列为InSequence[0…left-1], 分别为原序列的子串, 构造右子树同样, 显然可以用递归方法解决。算法如下:

//根据前序遍历序列和中序遍历序列构造二叉树 void CreateBT1(BTNode* &T, string pre, string in) {    if(pre.length()==0) {        T=NULL;        return;     }    char nodeVal = pre[0];    int index = in.find(nodeVal);    string lin = in.substr(0,index);    string rin = in.substr(index+1);    int leftChildLength = lin.length();    string lpre = pre.substr(1,leftChildLength);    string rpre = pre.substr(leftChildLength+1);    T = new BTNode(nodeVal);    CreateBT1(T->left,lpre,lin);    CreateBT1(T->right,rpre,rin);}

根据中序序列和后续序列构造二叉树

定理2 任何(n>=0)个不同节点的二叉树,都可由它的中序序列和后序序列唯一地确定。
  构造过程类似,算法如下:

//根据中序遍历序列和后序遍历序列构造二叉树void CreateBT2(BTNode* &T, string in, string post) {    int len = post.length();    if(len == 0) {        T = NULL;        return;    }    char nodeVal = post[len-1];    int index = in.find(nodeVal);    string lin = in.substr(0,index);    string rin = in.substr(index+1);    int leftChildLength = lin.length();    int rightChildLength = rin.length();    string lpost = post.substr(0,leftChildLength);    string rpost = post.substr(leftChildLength,rightChildLength);    T = new BTNode(nodeVal);    CreateBT2(T->left,lin,lpost);    CreateBT2(T->right,rin,rpost);}

完整测试代码

#include<iostream>#include<string>#include<algorithm>using namespace std;struct BTNode {    char val;    BTNode *left;    BTNode *right;     BTNode(char c) : val(c),left(NULL),right(NULL) {}};//根据前序遍历序列和中序遍历序列构造二叉树 void CreateBT1(BTNode* &T, string pre, string in) {    if(pre.length()==0) {        T=NULL;        return;     }    char nodeVal = pre[0];    int index = in.find(nodeVal);    string lin = in.substr(0,index);    string rin = in.substr(index+1);    int leftChildLength = lin.length();    string lpre = pre.substr(1,leftChildLength);    string rpre = pre.substr(leftChildLength+1);    T = new BTNode(nodeVal);    CreateBT1(T->left,lpre,lin);    CreateBT1(T->right,rpre,rin);}//根据中序遍历序列和后序遍历序列构造二叉树void CreateBT2(BTNode* &T, string in, string post) {    int len = post.length();    if(len == 0) {        T = NULL;        return;    }    char nodeVal = post[len-1];    int index = in.find(nodeVal);    string lin = in.substr(0,index);    string rin = in.substr(index+1);    int leftChildLength = lin.length();    int rightChildLength = rin.length();    string lpost = post.substr(0,leftChildLength);    string rpost = post.substr(leftChildLength,rightChildLength);    T = new BTNode(nodeVal);    CreateBT2(T->left,lin,lpost);    CreateBT2(T->right,rin,rpost);}//前序遍历(递归) void PreOrder(BTNode *root) {    if(root) {        cout<<root->val<<" ";        PreOrder(root->left);        PreOrder(root->right);      }}//中序遍历(递归)void InOrder(BTNode *root) {    if(root) {        InOrder(root->left);        cout<<root->val<<" ";        InOrder(root->right);    }}//后序遍历(递归)void PostOrder(BTNode *root) {    if(root) {        PostOrder(root->left);        PostOrder(root->right);        cout<<root->val<<" ";    }} //测试用例 int main() {    cout<<"根据前序遍历序列和中序遍历序列构造二叉树"<<endl;     BTNode *t;      string presequence = "ABCDEFG";      string insequence = "CBEDAFG";    CreateBT1(t,presequence,insequence);     cout<<"前序遍历:";       PreOrder(t);      cout<<"中序遍历:";    InOrder(t);     cout<<endl;    cout<<"根据中序遍历序列和后序遍历序列构造二叉树"<<endl;    BTNode *n;    string in = "DGBAECF";    string post = "GDBEFCA";    CreateBT2(n,in,post);    cout<<"中序遍历:";    InOrder(n);     cout<<"后序遍历:";     PostOrder(n);    return 0;  }

  运行结果如下:
这里写图片描述

0 0
原创粉丝点击