重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的谦虚遍历和中序遍历的结果中都不含重复的数字。

#include <iostream>
#include <string>
using namespace std;

int find(const string &str, char c) //在字符串中查找字符的函数,参数是string类引用和字符
{
   for (int i = 0; i < str.size(); ++ i)
      if (c == str[i])
        return i;                           //找到之后返回
        return -1;
}

void PreMid(const string &pre, const string &mid)    //参数是前序字符串引用和中序字符串引用
{
 if (pre.size() == 0)
  return ;                //前序字符串为空

 if(pre.size() != mid.size()) {                           //如果输入的序列长度不一样,那就无从谈重构 

     cout<<"error!!!"<<endl;
 }

if(mid[0] == mid[mid.size()-1] && pre[0] == pre[pre.size()-1]){
  if(pre[0] == mid[0]){
   cout << pre;    //输出叶子结点的值
   return;
  }
  else{
   cout<<"help1"<<endl;
   throw std::exception("error1");
  }
 }

 
 //根节点是第一个元素
 int k = find(mid, pre[0]);   //在中序中寻找前序的第一个字符(根节点)

 if(k == -1){
  cout<<"SOS"<<endl;
  throw std::exception("error2");
 }

//构造左子树

 string pretmp = pre.substr(1, k);  //第一个位置开始复制k个字符
 string midtmp = mid.substr(0, k);
 PreMid(pretmp, midtmp);

//构造右子树

 pretmp = pre.substr(k + 1, pre.size() - k - 1);
 midtmp = mid.substr(k + 1, mid.size() - k - 1);
 PreMid(pretmp, midtmp);

 //变成后序遍历要最后输出节点的值
 cout << pre[0];       //输出非叶子结点的值
}


int main()
{
 string pre, mid;
 while (cin >> pre >> mid){
  PreMid(pre, mid);
  cout << endl;
 }

 return 0;
}

PS: 1.在终止条件判断是需要写成两个if语句,三个终止条件必须同时成立是才直接返回。如果pre[0] != mid[0]则两个序列无法重构二叉树,应该抛出异常。

  2.三个条件都成立的话,则打印叶结点,并返回。

  3.第二个抛出异常的地方也是无法重构二叉树的,在中序遍历中无法找到根结点。

  4.这种方法是用字符串作为参数的,如果用整型数组呢?

  5.basic_string substr(size_type _Off,size_type _Count) const;  

    功能:从一个字符串复制一个从指定位置开始,并具有指定长度的子字符串。

  6.代码的健壮性需要注意。

posted @ 2012-12-09 11:17  Tiu.G  阅读(197)  评论(0编辑  收藏  举报