1.二叉树的创建(#号发)
1.为什么出现#方法创建树
先序遍历,字符串"12345"是不能确定一棵树的
请思考:会有多少种形状
#创建树,让树的每一个结点都变成度数为2的树
124###3##可以唯一确定一棵树吗?
2.#创建树练习
先序遍历:ABDH#K###E##CFI###G#J##,请画出树的形状
3.代码思路:利用前序遍历来建树(结点值陆续从键盘输入,用DLR为宜)
Bintree createBTpre()
{
Bintree T; char ch;
scanf("%c",&ch);
if(ch=='#') T=NULL;
else
{
T=(Bintree)malloc(sizeof(BinTNode));
T->data=ch;
T->lchild=createBTpre();
T->rchild=createBTpre();
}
return T;
}
//释放树
void BiTree_Free(BiTNode* T)
{
BiTNode* tmp=NULL;
if(T!=NULL)
{
if(T->rchild!=NULL) BiTree_Free(T->rchild);
if(T->lchild!=NULL) BiTree_Free(T->lchild);
if(T!=NULL)
{
free(T);
T=NULL;
}
}
}
后序遍历销毁一个树
结论:通过中序遍历和先序遍历可以确定一个树
通过中序遍历和后序遍历可以确定一个树
通过先序遍历和后序遍历确定不了一个树
单独先序遍历,能求解根,但不能求解左子树和右子树的结束、开始分界线
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
*/
//二叉链表示法
struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
};
typedef struct BiTNode BiTNode;
typedef struct BiTNode* BiTree;
void inOrder(BiTNode *root)
{
if (root == NULL)
{
return;
}
//遍历左子树
inOrder(root->lchild);
printf("%d ", root->data);
//遍历右子树
inOrder(root->rchild);
}
int Depth(BiTNode *T)
{
int deptleft = 0;
int deptright = 0;
int deptval = 0;
if (T == NULL)
{
deptval = 0;
return deptval;
}
//求左子树的高度
deptleft = Depth(T->lchild);
//求右子树的高度
deptright = Depth(T->rchild);
//+1
deptval = 1 + (deptleft>deptright ? deptleft:deptright);
return deptval;
}
BiTNode * CopyTree(BiTNode *T)
{
BiTNode *newNode = NULL;
BiTNode *newLp = NULL;
BiTNode *newRp = NULL;
if (T == NULL)
{
return NULL;
}
//copy左子树
if (T->lchild != NULL)
{
newLp = CopyTree(T->lchild); //copy左子树
}
else
{
newLp = NULL;
}
//copy右子树
if (T->rchild != NULL)
{
newRp = CopyTree(T->rchild);
}
else
{
newRp = NULL;
}
//malloc根节点
newNode = (BiTNode *)malloc(sizeof(BiTNode));
if (newNode == NULL)
{
return NULL;
}
newNode->lchild = newLp;
newNode->rchild = newRp;
newNode->data = T->data;
return newNode;
}
//1##
BiTNode * CreateBiThrTree(BiTNode* T)
{
BiTNode *node = NULL;
BiTNode *pL = NULL;
BiTNode *pR = NULL;
char h;
scanf("%c", &h);
if (h == '#')
{
return NULL;
}
else
{
node = (BiTNode*)malloc(sizeof(BiTNode));
memset(node, 0, sizeof(BiTNode));
node->data = h;
pL = CreateBiThrTree(); /*递归构造左子树*/
if (pL != NULL)
{
node->lchild = pL;
}
else
{
node->lchild = NULL;
}
pR = CreateBiThrTree(); /*递归构造右子树*/
if (pR != NULL)
{
node->rchild = pR;
}
else
{
node->rchild = NULL;
}
}
return node;
}
void main()
{
BiTNode t1, t2, t3, t4, t5;
memset(&t1, 0, sizeof(BiTNode));
memset(&t2, 0, sizeof(BiTNode));
memset(&t3, 0, sizeof(BiTNode));
memset(&t4, 0, sizeof(BiTNode));
memset(&t5, 0, sizeof(BiTNode));
t1.data = 1;
t2.data = 2;
t3.data = 3;
t4.data = 4;
t5.data = 5;
//建立关系
t1.lchild = &t2;
t1.rchild = &t3;
t2.lchild = &t4;
t3.lchild = &t5;
{
BiTNode* p = NULL;
p = CreateBiThrTree(p);
}
//树的遍历
printf("%d \n", Depth(&t1)) ;
{
BiTNode *root = CopyTree(&t1);
printf("\ncopy inorder\n");
inOrder(root);
printf("hello...\n");
}
printf("\nolder inorder\n");
inOrder(&t1);
printf("hello...\n");
system("pause");
return ;
}
2.中序和先序创建树
算法:
1.通过先序遍历找到根节点A,再通过A在中序遍历的位置找出左子树,右子树
2.在A的左子树中,找左子树的根节点(在先序中找),转步骤1
3.在A的右子树中,找右子树的根节点(在先序中找),转步骤1
讲解:
先序遍历结果:ADEBCF
中序遍历结果:DEACFB
练习:
先序遍历结果:ABDHKECFIGJ
中序遍历结果:HKDBEAIFCGJ