typedef struct BitNode
{
char data;
struct BitNode* lchild, * rchild;
}BitNode, * BiTree;
//BiTree 相当于 struct BitNode * BiTree;
前序:先访问树的根节点然后是左子树,最后是右子树。
中序:先访问树的左子树,然后是根节点,最后是右子树。
后序:先访问树的左子树,然后右子树,最后是根节点,。
为什么一种遍历方法不能建立,相信大家都懂了。
思路:(1)通过先序遍历找到根结点,再通过根结点在中序遍历的位置找出左子树、右子树。(2)根据左子树在先序遍历结果的顺序,找到左子树的根结点,视左子树为一棵独立的树,转步骤(1)。(3)根据右子树在先序遍历结果的顺序,找到右子树的根结点,视右子树为一棵独立的树,转步骤(1)。
void BuildTree(BiTree & T, char* pre_str, char* in_str, int L1, int R1, int L2, int R2)
{
T = (BitNode*)malloc(sizeof(BitNode));//申请一个节点
T->data = pre_str[L1];//判断用中序,赋值用先序
int in_root = 0;
for (int i = L2; i <= R2; i++)//找出中序遍历中根节点的位置
{
if (pre_str[L1] == in_str[i])
{
in_root = i;
break;
}
}
if (in_root - L2 != 0)//判断中序序列左边是否存在子序列
{
//递归构建左子树,包含两个区间,分别为前序、中序序列的左子树区间
BuildTree(T->lchild, pre_str, in_str, L1 + 1, L1 + in_root - L2, L2, in_root - 1);
}
else
T->lchild = NULL;//没有的话置为空
if (R2 - in_root != 0)//判断中序序列右边是否存在子序列
{
//递归构建右子树,包含两个区间,分别为前序、中序序列的右子树区间
BuildTree(T->rchild, pre_str, in_str, R1 - (R2 - in_root) + 1, R1, in_root + 1, R2);
}
else
T->rchild = NULL;
}
int main()
{
char pre[100], in[100];
printf_s("请输入先序:");
scanf_s("%s", pre,100);
printf_s("请输入中序:");
scanf_s("%s", in,100);
BiTree T = NULL;
int len1 = strlen(pre), len2 = strlen(in);
BuildTree(T, pre, in, 0, len1 - 1, 0, len2 - 1);
lastOrder(T);
return 0;
}
先序:ADEBCF
中序:DEACFB
//递归构建左子树,包含两个区间,分别为前序、中序序列的左子树区间
BuildTree(T->lchild, pre_str, in_str, L1 + 1, L1 + in_root - L2, L2, in_root - 1);
A为根节点,由中序知道DE为左子树,L1 + 1为先序中的D,L1 + in_root - L2为先序中的E,in_root - 1为中序中的E
同理可以知道左子树中参数的意义
只能用先序建立
BiTree creat_Tree()
{
BiTree T = NULL;
char ch;
scanf_s("%c", &ch);
if (ch == '#')
{
T = NULL;//说明该元素无效
return T;
}
else
{
T = (BitNode*)malloc(sizeof(BitNode));
if (T == NULL)//递归结束标识
return NULL;
T->data = ch;
T->lchild = NULL;//先置空
T->rchild = NULL;
T->lchild = creat_Tree();
T->rchild = creat_Tree();
return T;
}
}