# 二叉树的建立方法总结

### 1. 交互式问答方式

#include <cstdio>
#include <cstdlib>

using namespace std;

typedef struct BTNode *Position;
typedef Position BTree;
struct BTNode
{
char data;
Position lChild, rChild;
};

BTree CreateBTree(BTree bt, bool isRoot)
{
char ch;
if (isRoot)
printf("Root: ");
fflush(stdin);         /* 清空缓存区 */
scanf("%c", &ch);
fflush(stdin);
if (ch != '#')
{
isRoot = false;
bt = new BTNode;
bt->data = ch;
bt->lChild = NULL;
bt->rChild = NULL;
printf("%c's left child is: ", bt->data);
bt->lChild = CreateBTree(bt->lChild, isRoot);
printf("%c's right child is: ", bt->data);
bt->rChild = CreateBTree(bt->rChild, isRoot);
}
return bt;
}

int main()
{
BTree bt;
bt = CreateBTree(bt, true);
LevelOrderTraversal(bt);        /* 层序遍历 */

return 0;
}

### 2. 根据先序序列

BTree CreateBTree()
{
BTree bt = NULL;
char ch;
scanf("%c", &ch);
if (ch != '#')
{
bt = new BTNode;
bt->data = ch;
bt->lChild = CreateBTree();
bt->rChild = CreateBTree();
}
return bt;
}

### 3. 根据中序序列和后序序列

/*

ABCEFGHD
ABFHGEDC

*/
#include <cstdio>
#include <cstdlib>

using namespace std;

const int N = 1010;

typedef struct BTNode *Position;
typedef Position BTree;
struct BTNode
{
char data;
Position lChild, rChild;
};

BTree CreateBTree(char inOd[], char postOd[], int n);
void PreOrder(BTree bt);

int main()
{
char inOd[N], postOd[N];  /* 中序序列与后序序列 */
int n = 0;
char ch;
while ((ch = getchar()) && ch != '\n')
inOd[n++] = ch;
n = 0;
while ((ch = getchar()) && ch != '\n')
postOd[n++] = ch;

BTree bt = CreateBTree(inOd, postOd, n);
PreOrder(bt);
printf("\n");

return 0;
}

BTree CreateBTree(char inOd[], char postOd[], int n)
{
if (n == 0)
return NULL;

BTree btRoot = new BTNode;
btRoot->data = postOd[n-1];     //后序序列最后一个元素一定是根节点
char lInOd[N], rInOd[N];
char lPostOd[N], rPostOd[N];
int n1, n2;
n1 = n2 = 0;
//根据根节点将中序序列分为左子树和右子树
for (int i = 0; i < n; i++)
{
if (i <= n1 && inOd[i] != btRoot->data)
lInOd[n1++] = inOd[i];
else if (inOd[i] != postOd[n-1])
rInOd[n2++] = inOd[i];
}
//根据一个树的后序序列的长度等于中序序列且后序遍历是先左子树再右子树
//将后序序列分为左子树和右子树
int m1, m2;
m1 = m2 = 0;
for (int i = 0; i < n-1; i++)
{
if (i < n1)
lPostOd[m1++] = postOd[i];
else
rPostOd[m2++] = postOd[i];
}
btRoot->lChild = CreateBTree(lInOd, lPostOd, n1);
btRoot->rChild = CreateBTree(rInOd, rPostOd, n2);
return btRoot;
}

void PreOrder(BTree bt)
{
if (bt != NULL)
{
printf("%c", bt->data);
PreOrder(bt->lChild);
PreOrder(bt->rChild);
}
}

### 4. 根据不完整的先序，中序，后序序列

一棵二叉树的先序、中序和后序序列分别如下，其中一部分未显示出来，试编程求出空格处的内容。

先序：_B_F_ICEH_G

中序：D_KFIA_EJC_

后序：_K_FBHJ_G_A

/*

_B_F_ICEH_G
D_KFIA_EJC_
_K_FBHJ_G_A

ABDFKICEHJG
DBKFIAHEJCG
DKIFBHJEGCA

*/

#include <cstdio>
#include <cstdlib>

using namespace std;

const int N = 1010;

typedef struct BTNode *Position;
typedef Position BTree;
struct BTNode
{
char data;
Position lChild, rChild;
};

BTree CreateBTree(char preOd[], char inOd[], char postOd[], int n);
void PreOrder(BTree bt);
void InOrder(BTree bt);
void PostOrder(BTree bt);

int main()
{
char preOd[N], inOd[N], postOd[N];
int n = 0;
char ch;
while ((ch = getchar()) && ch != '\n')
preOd[n++] = ch;
n = 0;
while ((ch = getchar()) && ch != '\n')
inOd[n++] = ch;
n = 0;
while ((ch = getchar()) && ch != '\n')
postOd[n++] = ch;

BTree bt = CreateBTree(preOd, inOd, postOd, n);
PreOrder(bt);
printf("\n");
InOrder(bt);
printf("\n");
PostOrder(bt);
printf("\n");

return 0;
}

BTree CreateBTree(char preOd[], char inOd[], char postOd[], int n)
{
if (n == 0)
return NULL;
BTree btRoot = new BTNode;
if (n == 1)
{
if (preOd[0] != '_')
btRoot->data = preOd[0];
else if (inOd[0] != '_')
btRoot->data = inOd[0];
else if (postOd[0] != '_')
btRoot->data = postOd[0];
else
{
printf("Input error!\n");
exit(0);
}
btRoot->lChild = NULL;
btRoot->rChild = NULL;
return btRoot;
}
if (postOd[n-1] != '_')
btRoot->data = postOd[n-1];     //后序序列最后一个元素一定是根节点
else if (preOd[0] != '_')
btRoot->data = preOd[0];
else
{
printf("Input Error!\n");
exit(0);
}
char lPreOd[N], rPreOd[N];
char lInOd[N], rInOd[N];
char lPostOd[N], rPostOd[N];
int n1, n2;
n1 = n2 = 0;
//根据根节点将中序序列分为左子树和右子树
int flag = 0;   //判断根节点是否在中序序列中
for (int i = 0; i < n; i++)
{
if (inOd[i] == btRoot->data)
{
flag = 1;
break;
}
}
if (flag == 1)  //如果根节点存在，按根节点划分
{
for (int i = 0; i < n; i++)
{
if (i <= n1 && inOd[i] != btRoot->data)
lInOd[n1++] = inOd[i];
else if (inOd[i] != btRoot->data)
rInOd[n2++] = inOd[i];
}
}
else        //如果根节点不存在，按'_'划分
{
for (int i = 0; i < n; i++)
{
if (i <= n1 && inOd[i] != '_')
lInOd[n1++] = inOd[i];
else if (inOd[i] != '_')
rInOd[n2++] = inOd[i];
}
}

//根据一个树的后序序列的长度等于中序序列且后序遍历是先左子树再右子树
//将后序序列分为左子树和右子树
int m1, m2;
m1 = m2 = 0;
for (int i = 0; i < n-1; i++)
{
if (i < n1)
lPostOd[m1++] = postOd[i];
else
rPostOd[m2++] = postOd[i];
}
//根据一个树的先序序列的长度等于中序序列且先序遍历是除根节点外也是先左子树再右子树
//将先序序列分为左子树和右子树
m1 = m2 = 0;
for (int i = 1; i < n; i++)
{
if (i < n1 + 1)
lPreOd[m1++] = preOd[i];
else
rPreOd[m2++] = preOd[i];
}
btRoot->lChild = CreateBTree(lPreOd, lInOd, lPostOd, n1);
btRoot->rChild = CreateBTree(rPreOd, rInOd, rPostOd, n2);

return btRoot;
}

void PreOrder(BTree bt)
{
if (bt != NULL)
{
printf("%c", bt->data);
PreOrder(bt->lChild);
PreOrder(bt->rChild);
}
}

void InOrder(BTree bt)
{
if (bt != NULL)
{
InOrder(bt->lChild);
printf("%c", bt->data);
InOrder(bt->rChild);
}
}

void PostOrder(BTree bt)
{
if (bt != NULL)
{
PostOrder(bt->lChild);
PostOrder(bt->rChild);
printf("%c", bt->data);
}
}
View Code

posted @ 2015-10-24 12:56  llhthinker  阅读(47909)  评论(2编辑  收藏  举报
TOP