6+重建二叉树

来源:互联网 发布:tr罗马布特黑淘宝 编辑:程序博客网 时间:2024/06/05 20:24
title:
输入二叉树的前序和中序的遍历结果,要求重建该二叉树


thought:

一般涉及到二叉树(左右子树)的操作,都会考虑用到递归方法;
1、创建一个新节点,由前序得到根节点,将其赋给新节点,再找到根节点在中序中的位置root_in,根据这一位置计算出左子树的长度len;
   当数中只剩下一个节点时,就返回这一节点,此语句是递归结束语句;!!
2、根据左子树的长度计算出左子树的尾节点在位于前序的位置;
3、当左子树确定后,如果左子树的长度<整个树的长度,说明右子树不为空;
   前序中:根节点之后的前len个节点为左子树,后面的属于右子树;
   中序中:root_in前面的属于左子树,后面的属于右子树;
4、在3中的左右子树中分别循环1、2、3操作(递归);

注:
需要考虑的特殊情况:
输入的二叉树为空
单节点二叉树
无左子树的二叉树
无右子树的二叉树

前序和中序不匹配的二叉树

#include <iostream>#include <string>using namespace std;struct Btree{int b_value;Btree *b_left;Btree *b_right;};Btree *Rebuild(int *Preorder,int *Inorder,int len); //输入前序和中序序列,重建二叉树Btree *Rebuild_subtree(int *start_pre,int *end_pre,int *start_in,int *end_in);   //重建二叉树函数中的核心递归实现void pre_traverse(Btree *bt);void in_traverse(Btree *bt);void post_traverse(Btree *bt);Btree *Rebuild(int *Preorder,int *Inorder,int len){if(NULL == Preorder || NULL == Inorder || len <= 0)return NULL;return Rebuild_subtree(Preorder,Preorder+len-1,Inorder,Inorder+len-1);}Btree *Rebuild_subtree(int *start_pre,int *end_pre,int *start_in,int *end_in){Btree *root = new Btree;                 //创建一个头结点(前序遍历的第一个结点就是头结点)root->b_left = NULL;root->b_right = NULL;root->b_value = start_pre[0];int root_value = start_pre[0];if(start_pre == end_pre)        {if(start_in == end_in && *start_pre == *start_in) //判断二叉树中是否为单结点return root;elsethrow exception("Invaild input!");           //抛出异常}int *root_in = start_in;                           //从前序中获得头结点的valuewhile (root_value != *root_in && start_in <= end_in)   //在中序中找到值等于value的结点,此节点前面的就是左子树,后面的就是右子树root_in++;if(root_in == end_in && *root_in != *end_in)    //当根结点指针与中序的最后结点指针指向同一个地址,但是其各自的值不相等,则抛出一个异常!(即输入的前序和中序不匹配)throw exception("Invaild input!");int left_length = root_in-start_in;                   //计算左子树的长度int *left_end_pre = start_pre+left_length;           //根据左子树的长度计算出左子树在前序中的截止位置(由头结点的下一个节点开始,到截止位置,此序列为头结点的左子树)if(left_length > 0)                             //当左子树存在时,在左子树中递归重建root->b_left = Rebuild_subtree(start_pre+1,left_end_pre,start_in,root_in-1);if(left_length < end_pre-start_pre)           //当右子树存在时,在右子树中递归重建root->b_right = Rebuild_subtree(left_end_pre+1,end_pre,root_in+1,end_in);return root;}void pre_traverse(Btree *bt){if(NULL == bt){cout <<"二叉树为空!" << endl;return;}cout<< "  " <<bt->b_value;if(bt->b_left != NULL) pre_traverse(bt->b_left);if(bt->b_right != NULL) pre_traverse(bt->b_right);}void in_traverse(Btree *bt){if(NULL == bt){cout <<"二叉树为空!" << endl;return;}if(bt->b_left != NULL) in_traverse(bt->b_left);cout<< "  " <<bt->b_value;if(bt->b_right != NULL) in_traverse(bt->b_right);}void post_traverse(Btree *bt){if(NULL == bt){cout <<"二叉树为空!" << endl;return;}if(bt->b_left != NULL) post_traverse(bt->b_left);if(bt->b_right != NULL) post_traverse(bt->b_right); cout<< "  " <<bt->b_value;}int main(){/*普通二叉树*///int Pre[] = {1,2,4,7,3,5,6,8};//int In[] = {4,7,2,1,5,3,8,6};/*无右子树的二叉树(所有节点都无右子树)*///int Pre[] = {1,2,3,4};//int In[] = {4,3,2,1};/*无左子树的二叉树(所有节点都无左子树)*///int Pre[] = {1,2,3,4};//int In[] = {1,2,3,4};/*前序和后序不匹配的二叉树*/int Pre[] = {1,2,4,7,3,5,6,8};int In[] = {4,7,2,1,9,3,8,6}; //抛出异常int Len = sizeof(Pre)/sizeof(int);Btree *bt = Rebuild(Pre,In,Len);cout << "重建二叉树的前序遍历结果:" << endl;pre_traverse(bt);cout << endl;cout << "重建二叉树的中序遍历结果:" << endl; in_traverse(bt); cout << endl;cout << "重建二叉树的后序遍历结果:" << endl;post_traverse(bt);cout << endl;return 0;}



0 0
原创粉丝点击