重建二叉树

来源:互联网 发布:idea蓝色java目录 编辑:程序博客网 时间:2024/05/09 23:06

     对二叉树有点了解的都知道,通过中序和任何遍历都可以唯一构建好一个二叉树,所以我们可以以中序和前序为例,来重建一棵二叉树:

#include <iostream>using namespace std;struct tree_node  //树节点的结构体{int m_data;tree_node *m_cright;tree_node *m_cleft;};class solution{public:tree_node* Recreate(int *preorder,int *inorder,int length) //形参分别表示前序遍历,中序遍历和长度{if(preorder==NULL||inorder==NULL||length<=0)return NULL;return _create(preorder,preorder+length-1,inorder,inorder+length-1);}//递归后序遍历void backorder(tree_node *root){if(root==NULL)return;backorder(root->m_cleft);backorder(root->m_cright);cout<<root->m_data<<" ";}private:tree_node* _create(int *start_pre,int *end_pre,int *start_in,int *end_in){//根据前序遍历的第一个数据是根节点int root_data=start_pre[0];//取出当前的根节点tree_node* root=new tree_node; //在堆中开辟保存根节点的内存root->m_cleft=NULL;root->m_cright=NULL;root->m_data=start_pre[0];if(start_pre==end_pre)//当前只有一个结点,没有左右子树了{if(start_in==end_in&&*start_pre==*start_in)//中序遍历数组也只有一个元素,且和前序遍历的数据相等,则输入正确{return root;}elsethrow std::exception("无效的输入");}//在中序遍历中找到根节点的位置int* root_position=start_in;while(root_position<=end_in&&*root_position!=root_data)++root_position;if(root_position==end_in&&*root_position!=root_data)//到达末尾还不相等,则匹配错误throw std::exception("匹配错误"); //匹配错误int left_num=root_position-start_in ;//左子树的个数if(left_num>0){root->m_cleft=_create(start_pre+1,start_pre+left_num,start_in,root_position-1);}if(left_num<end_in-start_in) //还有右子数{root->m_cright=_create(start_pre+left_num+1,end_pre,root_position+1,end_in);}return root;}};int main(){solution s;int preorder[8]={1,2,4,7,3,5,6,8};int inorder[8]={4,7,2,1,5,3,8,6};tree_node *root=s.Recreate(preorder,inorder,8);s.backorder(root);}
思路:通过前序遍历的第一个元素可以得到该二叉树的根节点,,然后在中序遍历的数组中找到根节点(由前序遍历得到),中序遍历的数组中根节点的左边是左子树,右边是右字数,然后由左右子树的个数在前序遍历中分别找到左右子树的前序遍历,然后由左右子树的前序和中序遍历得到子树的根节点,一次类推。。。用递归的方式就可以重建好二叉树。

总结:

    中序+前序、后序、层次遍历可以唯一地确定一个二叉树;

     前序、后序、层次遍历中的任意两个遍历都不能唯一地确定一个二叉树。

0 0