题目
给定一棵二叉树的先序和后序序列,构造出这棵二叉树。假设二叉树中每个节点存放的是不同的字符。如:先序序列为:abdcef,后序序列为:“dbaecf。
思路:
由于二叉树的定义就是递归的,因此很多和二叉树相关的题目都可以递归来实现。
code:
/*
* =====================================================================================
*
* Filename: Rebuild.cpp
*
* Description: Rebuild binary tree based on preorder traversal and inorder traversal
*
* Version: 1.0
* Created: 2012年10月07日 00时29分05秒
* Revision: none
* Compiler: gcc
*
* Author: lonfee88 (), lonfee88@gmail.com
* Company: nlp.whu
*
* =====================================================================================
*/
#include<iostream>
using namespace std;
struct NODE
{
NODE *pLeft;
NODE *pRight;
char chValue;
};
void Rebuild(char *pPreOrder, char *pInOrder, int nTreeLen, NODE **pRoot)
{
cout << "Rebuild" << "(" <<pPreOrder<<"," << pInOrder << ","<<nTreeLen <<")" << endl;
int i;
NODE *pLeft=NULL,*pRight=NULL;
if(nTreeLen>0)
{
for(i=0;i<nTreeLen;i++)
if(pPreOrder[0] == pInOrder[i])
break;
cout << i <<endl;
cout << "\tRebuild left" << "(" <<pPreOrder+1<<"," << pInOrder << ","<<i <<")" << endl;
Rebuild(pPreOrder+1,pInOrder,i,&pLeft);
cout << "\tRebuild right" << "(" <<pPreOrder+i+1<<"," << pInOrder+i+1 << ","<<nTreeLen-i-1 <<")" << endl;
Rebuild(pPreOrder+i+1,pInOrder+i+1,nTreeLen-i-1,&pRight);
cout << "construct node "<< *pPreOrder << endl;
*pRoot=new NODE;
(*pRoot) -> pLeft = pLeft;
(*pRoot) -> pRight = pRight;
(*pRoot) -> chValue = *pPreOrder;
}
}
void preTraversal(NODE *pRoot)
{
if(pRoot!=NULL)
{
cout<<pRoot->chValue;
preTraversal(pRoot->pLeft);
preTraversal(pRoot->pRight);
}
}
void inTraversal(NODE *pRoot)
{
if(pRoot!=NULL)
{
inTraversal(pRoot->pLeft);
cout<<pRoot->chValue;
inTraversal(pRoot->pRight);
}
}
void postTraversal(NODE *pRoot)
{
if(pRoot!=NULL)
{
postTraversal(pRoot->pLeft);
postTraversal(pRoot->pRight);
cout<<pRoot->chValue;
}
}
int main(int argc, char *argv[])
{
const int TREELEN = 6;
char szPreOrder[TREELEN] = {'a','b','d','c','e','f'};
char szInOrder[TREELEN] = {'d','b','a','e','c','f'};
NODE *pRoot = NULL;
Rebuild(szPreOrder, szInOrder, TREELEN, &pRoot);
//NODE **pRoot = NULL;
//Rebuild(szPreOrder, szInOrder, TREELEN, pRoot);
cout<<"Verify:"<<endl;
cout<<"PreOrder:";
preTraversal(pRoot);
cout<<endl;
cout<<"InOrder:";
inTraversal(pRoot);
cout<<endl;
cout<<"PostOrder:";
postTraversal(pRoot);
cout<<endl;
return 0;
}
注意:
1. C++中stuct声明的类型可以不带关键字,如声明NODE如下:
struct NODE
{
NODE *pLeft;
NODE *pRight;
char chValue;
};
后面可以直接用NODE来声明新的变量
NODE *pLeft=NULL,*pRight=NULL;
而不用像C语言中那样,必须带有stuct关键字,即用stuct NODE来声明新的变量。
这是因为C++把stuct当作类来处理。
2.二级指针初始化的问题
如果想初始化指针的指针为NULL,应该这么来
NODE *pRoot = NULL;
Rebuild(szPreOrder, szInOrder, TREELEN, &pRoot);
初始化之后,可以直接引用*pRoot.
下面这样声明就不能直接引用*pRoot:
NODE **pRoot = NULL;
Rebuild(szPreOrder, szInOrder, TREELEN, pRoot);
总之,把指针当作地址来思考,一切就都解释得通了。