您的位置:首页 > 其它

通过中序遍历和先序遍历结果构造二叉树

2013-09-29 18:57 211 查看
1. 给出中序遍历和先序遍历结果,构造二叉树

// ConstructTree.cpp : 定义控制台应用程序的入口点。
//

#include "stdio.h"
#include "stdlib.h"
#include "iostream"
#include "vector"
#include "stack"

using namespace std;

typedef struct Node
{
int data;
struct Node * lc;
struct Node * rc;
}TreeNode, *TNode;

void Construct(int * inorderStart, int * inorderEnd, int * &preIndex, Node * &root);
void InOrder(Node * root);

int main(int argc, char * argv[])
{
int preOrder[] = {1, 2, 4, 7, 3, 5, 6, 8};
int inOrder[] =  {4, 7, 2, 1, 5, 3, 8, 6};

Node * tree;

int * inorderStart = inOrder;
int * inorderEnd = inOrder + 7;
int * preorder = preOrder;

Construct(inorderStart, inorderEnd, preorder, tree);
cout<<endl;
InOrder(tree);

system("pause");
return 0;
}

// 通过中序遍历序列和先序遍历序列,构造二叉树,
// 还可以在构造的构成中输出后续遍历结果
// 地柜的调用
void Construct(int * inorderStart, int * inorderEnd, int * &preIndex, Node * &root)
{
// 没有左子树
if(inorderEnd < inorderStart)
return;
// 没有右子树
if(inorderStart > inorderEnd)
return;

root = new Node;
int data = *preIndex;
root->data = data;
root->lc = NULL;
root->rc = NULL;

if(inorderStart == inorderEnd)
{
// 遍历到叶子节点,相当于左右子树都为空
printf("%3d", root->data);
return;
}

// 找到先序遍历的点在中序序列中的位置
// 通过该位置递归的构造左子树和右子树
int * pc = inorderStart;
while(*pc != data)
{
pc++;
}

if(pc > inorderStart)
{
preIndex++;
Construct(inorderStart, pc - 1, preIndex, root->lc);
}

if(pc < inorderEnd)
{
preIndex++;
Construct(pc + 1, inorderEnd, preIndex, root->rc);
}

// 输出后续遍历结果
printf("%3d", root->data);
}

// 中序遍历
void InOrder(Node * root)
{
if(root)
{
InOrder(root->lc);
printf("%3d", root->data);
InOrder(root->rc);
}
}


2. 根据中序结果和后续结果构造二叉树

// ConstructTree.cpp : 定义控制台应用程序的入口点。
//

#include "stdio.h"
#include "stdlib.h"
#include "iostream"
#include "vector"
#include "stack"

using namespace std;

typedef struct Node
{
int data;
struct Node * lc;
struct Node * rc;
}TreeNode, *TNode;

void Construct(int * inorderStart, int * inorderEnd, int * &preIndex, Node * &root);
void Construct2(int * inorderStart, int * inorderEnd, int * &preIndex, Node * &root);
void InOrder(Node * root);

int main(int argc, char * argv[])
{
int preOrder[]  = {1, 2, 4, 7, 3, 5, 6, 8};
int inOrder[]   = {4, 7, 2, 1, 5, 3, 8, 6};
int postOrder[] = {7, 4, 2, 5, 8, 6, 3, 1};

Node * tree;

int * inorderStart = inOrder;
int * inorderEnd = inOrder + 7;
int * preorder = preOrder;

cout<<"构造二叉树,后续遍历"<<endl;
Construct(inorderStart, inorderEnd, preorder, tree);
cout<<endl;
cout<<"中序遍历"<<endl;
InOrder(tree);
cout<<endl;

int * postorder = postOrder + 7;
cout<<"构造二叉树,递归书序,根据中序遍历和后续遍历结果构造二叉树"<<endl;
Construct2(inorderStart, inorderEnd, postorder, tree);
cout<<endl;
cout<<"中序遍历"<<endl;
InOrder(tree);

system("pause");
return 0;
}

// 通过中序遍历序列和先序遍历序列,构造二叉树,
// 还可以在构造的构成中输出后续遍历结果
// 地柜的调用
void Construct(int * inorderStart, int * inorderEnd, int * &preIndex, Node * &root)
{
// 没有左子树
if(inorderEnd < inorderStart)
return;
// 没有右子树
if(inorderStart > inorderEnd)
return;

root = new Node;
int data = *preIndex;
root->data = data;
root->lc = NULL;
root->rc = NULL;

if(inorderStart == inorderEnd)
{
// 遍历到叶子节点,相当于左右子树都为空
printf("%3d", root->data);
return;
}

// 找到先序遍历的点在中序序列中的位置
// 通过该位置递归的构造左子树和右子树
int * pc = inorderStart;
while(*pc != data)
{
pc++;
}

if(pc > inorderStart)
{
preIndex++;
Construct(inorderStart, pc - 1, preIndex, root->lc);
}

if(pc < inorderEnd)
{
preIndex++;
Construct(pc + 1, inorderEnd, preIndex, root->rc);
}

// 输出后续遍历结果
printf("%3d", root->data);
}

// 中序遍历
void InOrder(Node * root)
{
if(root)
{
InOrder(root->lc);
printf("%3d", root->data);
InOrder(root->rc);
}
}

// 通过给定的后续遍历,中序遍历结果,构造二叉树
void Construct2(int * inorderStart, int * inorderEnd, int * &preIndex, Node * &root)
{
// 没有左子树
if(inorderEnd < inorderStart)
return;
// 没有右子树
if(inorderStart > inorderEnd)
return;

root = new Node;
int data = *preIndex;
root->data = data;
root->lc = NULL;
root->rc = NULL;

if(inorderStart == inorderEnd)
{
// 遍历到叶子节点,相当于左右子树都为空
printf("%3d", root->data);
return;
}

// 找到先序遍历的点在中序序列中的位置
// 通过该位置递归的构造左子树和右子树
int * pc = inorderStart;
while(*pc != data)
{
pc++;
}

// 递归右子树
if(pc < inorderEnd)
{
preIndex--;
Construct2(pc + 1, inorderEnd, preIndex, root->rc);
}

// 递归左子树
if(pc > inorderStart)
{
preIndex--;
Construct2(inorderStart, pc - 1, preIndex, root->lc);
}

// 输出后续遍历结果
printf("%3d", root->data);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: