用二叉树的中序和前序还原二叉树

用二叉树的中序和前序还原二叉树
主要解答者:Betta提交人:langhaixin
感谢:totobi、leemars、Betta
审核者:starfish社区对应贴子:查看
     A :

假设二叉树T的结点值是字符,已知T中结点的前序和中序  
试编写一个把树T按标准形式进行存储的C函数。  
 
二叉树的标准存储形式为  
tpyedef  struct  bt  
{  
         char  data;  
         struct  bt  *lefttree;  
         struct  bt  *righttree;  
}  BinaryTree  
---------------------------------------------------------------  
 
BrinaryTree  *Q[maxsize];  
BrinaryTree  *CREATREE()  
{char  ch;  
 int  fornt,rear;  
 BrinaryTree  *root,*s;  
root=NULL;  
front=1;rear=0;  
ch=getchar();  
while(ch!='#')  
{s=NULL;  
   if(ch!='@')  
     {  
       s=malloc(sizeof(BinaryTree));  
       s->data=ch;  
       s->lefttree=Null;  
       s->righttree=Null;  
       }  
rear++;  
Q[rear]=s;  
if(rear==1)  root=s;  
else  
{if(s&&  Q[front])  
   if  (rear%2==0)  Q[front]->lefttree=s;  
   else    
       Q[front]->righttree=s;  
   if(rear%2==1)  front++;  
}  
ch=getchar;  
}  
return  root;  
}  
---------------------------------------------------------------  
 
我举个例子吧  
 
已知前序是ABCDEFG  中序是CBEDAFG  求二叉树  
 
首先从取前序第1个字母(A)  按此字母把中序分成两段  (CBED)  (AFG)  
A做根  (CBED)做左子树  (FG)右子树  
再按长度把前序后面的部分分成(BCDE)  (FG)  
 
问题就转换成  
已知前序是BCDE  中序是CBED  求二叉树  
和  
已经前序是FG  中序是FG  求二叉树  
 
看出来了没有,递归求解的.  
下面的步骤省略分析.  
前序  中序  :  根  左子树分解  右子树分解  
BCDE  CBED  :  B      (C)  (C)        (ED)  (DE)  
C        C        :  C  
DE   ED      :  D      (E)  (E)  
E        E        :  E  
 
FG      FG      :  F                            (G)  (G)  
G        G        :  G  
得出的二叉树就是  
         A  
       /  /  
     B      F  
   /  /      /  
 C      D      G  
       /  
     E  
 
---------------------------------------------------------------  
 
这个是按  LeeMaRS(小菜虎)  的算法描述写的程序:  
编译:  
//VC  
   cl  -GX  treep.cpp  
//gcc  
   g++  -o  treep  treep.cpp  
 
#include  <iostream>  
 
class  CTreeNode  
{  
public:              
           CTreeNode(char  cVal,  CTreeNode  *  pLeft=0,  CTreeNode  *  pRight=0)  
           :  m_cVal(cVal)  
           ,  m_pLeft(pLeft)  
           ,  m_pRight(pRight)  
           {  
           }  
           ~CTreeNode()  
           {  
                       if(m_pLeft  !=  0)  
                       {  
                                   delete  m_pLeft  ;  
                       }  
                       std::cout  <<  m_cVal  ;  
                       if(m_pRight  !=  0)  
                       {  
                                   delete  m_pRight  ;  
                       }  
           }  
           char  m_cVal  ;  
           CTreeNode  *  m_pLeft  ;  
           CTreeNode  *  m_pRight  ;  
}  ;  
 
 
CTreeNode  *  CreateNode(char  *  sPre,  char  *  sMid,  int  nSize)  
{  
           if(nSize  ==  0)  
                       return  0  ;  
           if(nSize  ==  1)  
                       return  new  CTreeNode(*sPre)  ;  
           int  nSplitMid  ;  
           for(nSplitMid=0;  nSplitMid<nSize;  ++nSplitMid)  
           {  
                       if(sMid[nSplitMid]  ==  sPre[0])  
                                   break  ;  
           }  
           if(nSplitMid  ==  nSize)  
                       return  0  ;  
           return  new  CTreeNode(*sPre,  CreateNode(sPre+1,  sMid,  nSplitMid),  
                       CreateNode(sPre+nSplitMid+1,  sMid+nSplitMid+1,  nSize-nSplitMid-1))  ;  
}  
 
int  main()  
{  
           CTreeNode  *  p  =  CreateNode("ABCDEFG",  "CBEDAFG",  7)  ;  
           if(p  !=  0)  
                       delete  p  ;  
           std::cout  <<  std::endl  ;  
           return  0  ;  
}  
### 回答1: 将二叉树前序遍历序列和中序遍历序列作为输入,可以通过递归地构造二叉树还原树。 下面给出 C 语言的实现: ``#include <stdio.h> #include <stdlib.h> // 定义结点 typedef struct TreeNode int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 从前序中序遍历构建二叉树 TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) { if (preorderSize == 0 || inorderSize == 0) { return NULL; } int root_val = preorder[0]; TreeNode *root = (TreeNode*)malloc(sizeof(TreeNode)); root->val = root_val; root->left = NULL; root->right = NULL; int i; for (i = 0; i < inorderSize; i++) { if (inorder[i] == root_val) { break; } } int left_tree_size = i; int right_tree_size = inorderSize - i - 1; root->left = buildTree(preorder + 1, left_tree_size, inorder, left_tree_size); root-> = buildTree(preorder + left_tree_size + 1, right_tree_size, inorder + left_tree_size + 1, right_tree_size); return root; } // 打印中序遍历结果 void printInorder(TreeNode *root) { if (root == NULL) { return; } printInorder(root->left); printf("%d ", root->val); printInorder(root->right); } int main() { int preorder[] = {3, 9, 20, 15, 7}; int inorder[] = {9, 3, 15, 20, 7}; TreeNode *root = buildTree(preorder, 5, inorder, 5); printInorder(root); return 0; } ``` 上述代码构建了一个二叉树,并打印了中序遍历结果。输出结果为 9 3 15 20 7。 ### 回答2: 二叉树前序遍历是指先访问根节点,再访问左子树,最后访问右子树;中序遍历是指先访问左子树,再访问根节点,最后访问右子树。 要还原一棵二叉树,首先需要知道它的前序遍历和中序遍历结果。可以通过递归的方式进行还原。 1. 首先,声明一个结构体表示二叉树节点: ```c typedef struct TreeNode { char data; struct TreeNode* left; struct TreeNode* right; } TreeNode; ``` 2. 接下来,实现一个函数以前序遍历和中序遍历结果作为参数,返回还原后的二叉树根节点: ```c TreeNode* buildTree(char* preorder, char* inorder, int length) { if (length <= 0) { return NULL; } // 创建根节点 TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode)); root->data = preorder[0]; root->left = NULL; root->right = NULL; // 找到根节点在中序遍历结果中的位置 int rootIndex = 0; while (inorder[rootIndex] != root->data) { rootIndex++; } // 分割左右子树的中序遍历结果 char* leftInorder = inorder; int leftLength = rootIndex; char* rightInorder = inorder + rootIndex + 1; int rightLength = length - rootIndex - 1; // 分割左右子树的前序遍历结果 char* leftPreorder = preorder + 1; int leftPreorderLength = leftLength; char* rightPreorder = preorder + leftPreorderLength + 1; int rightPreorderLength = rightLength; // 递归还原左右子树 root->left = buildTree(leftPreorder, leftInorder, leftLength); root->right = buildTree(rightPreorder, rightInorder, rightLength); return root; } ``` 3. 最后,在主函数中调用上述函数进行还原: ```c int main() { char* preorder = "ABCDEFG"; char* inorder = "CBDEAFG"; int length = strlen(preorder); TreeNode* root = buildTree(preorder, inorder, length); // 对还原后的二叉树进行操作 return 0; } ``` 通过以上步骤,就可以根据给定的前序遍历和中序遍历结果还原二叉树
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值