一個前序走訪序列和一個中序遍曆序列可以確定一顆唯一的二叉樹。
根據前序走訪的特點, 知前序序列(PreSequence)的首個元素(PreSequence[0])為二叉樹的根(root),
然後在中序序列(InSequence)中尋找此根(root), 根據中序遍曆特點, 知在尋找到的根(root) 前邊的序列為根的左子樹的中序遍曆序列, 後邊的序列為根的右子樹的中序遍曆序列。 設在中序遍曆序列(InSequence)根前邊有left個元素.
則在前序序列(PreSequence)中, 緊跟著根(root)的left個元素序列(即PreSequence[1...left])
為根的左子樹的前序走訪序列, 在後邊的為根的右子樹的前序走訪序列.而構造左子樹問題其實跟構造整個二叉樹問題一樣,只是此時前序序列為PreSequence[1...left]), 中序序列為InSequence[0...left-1],
分別為原序列的子串, 構造右子樹同樣, 顯然可以用遞迴方法解決。
二叉樹的定義於下:
//二叉鏈表表示二叉樹typedef struct BiNode{char data;//節點資料struct BiNode * lchild;//左孩子 struct BiNode * rchild;//右孩子}BiNode, * BiTree;
由前序走訪序列和中序遍曆序列確定一顆唯一的二叉樹的演算法餘下:
//由前序序列和中序序列建立二叉樹的過程void CreateBiTree(BiTree & t,string presequence,string insequence)//t為要建立的二叉樹,presequence和insequence分別為前序和中序序列{ if(presequence.length()==0) { t=NULL; return ; } char rootNode=presequence[0];//根 int index=insequence.find(rootNode);//根在中序序列中的位置 string lchild_insequence=insequence.substr(0,index);//左孩子的中序序列 string rchild_insequence=insequence.substr(index+1);//右孩子的中序序列 int lchild_length=lchild_insequence.length();//左孩子的長度 int rchild_length=rchild_insequence.length();//右孩子的長度 string lchild_presequence=presequence.substr(1,lchild_length);//左孩子的前序序列 string rchild_presequence=presequence.substr(1+lchild_length);//右孩子的前序序列 t=(BiTree)malloc(sizeof(BiNode)); if(t!=NULL) { t->data=rootNode; CreateBiTree(t->lchild,lchild_presequence,lchild_insequence);//遞迴建立左孩子 CreateBiTree(t->rchild,rchild_presequence,rchild_insequence);//遞迴建立右孩子 }}
完整程式碼餘下:
// 由前序序列和中序序列構造二叉樹.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <string>#include <iostream>using namespace std;//二叉鏈表表示二叉樹typedef struct BiNode{char data;//節點資料struct BiNode * lchild;//左孩子 struct BiNode * rchild;//右孩子}BiNode, * BiTree;//由前序序列和中序序列建立二叉樹的過程void CreateBiTree(BiTree & t,string presequence,string insequence)//t為要建立的二叉樹,presequence和insequence分別為前序和中序序列{ if(presequence.length()==0) { t=NULL; return ; } char rootNode=presequence[0];//根 int index=insequence.find(rootNode);//根在中序序列中的位置 string lchild_insequence=insequence.substr(0,index);//左孩子的中序序列 string rchild_insequence=insequence.substr(index+1);//右孩子的中序序列 int lchild_length=lchild_insequence.length();//左孩子的長度 int rchild_length=rchild_insequence.length();//右孩子的長度 string lchild_presequence=presequence.substr(1,lchild_length);//左孩子的前序序列 string rchild_presequence=presequence.substr(1+lchild_length);//右孩子的前序序列 t=(BiTree)malloc(sizeof(BiNode)); if(t!=NULL) { t->data=rootNode; CreateBiTree(t->lchild,lchild_presequence,lchild_insequence);//遞迴建立左孩子 CreateBiTree(t->rchild,rchild_presequence,rchild_insequence);//遞迴建立右孩子 }}//檢驗是否建立成功 //遞迴前序走訪二叉樹 void PreOrderTraverse(BiTree & t) { if(t!=NULL) { cout<<t->data; PreOrderTraverse(t->lchild); PreOrderTraverse(t->rchild); } } //遞迴中序序遍曆二叉樹void InOrderTraverse(BiTree & t) { if(t!=NULL) { InOrderTraverse(t->lchild); cout<<t->data; InOrderTraverse(t->rchild); } }int _tmain(int argc, _TCHAR* argv[]){ BiTree t;string presequence="ABCDEFG";string insequence ="CBEDAFG";CreateBiTree(t,presequence,insequence);PreOrderTraverse(t);cout<<endl;InOrderTraverse(t);system("PAUSE");return 0;}
結果如下: