二叉树的二叉链表结构:
typedef struct BiTNode
{
ElemType data;//数据域
struct BiTNode *lchild, *rchild;//两个指针域,分别指向左子树和右子树
}BiTNode,*BiTree;
创建一个二叉树:每生成一个新结点,如果该结点为空,就不用再递归生成左右子树结点。
Status CreateBiTree(BiTree &t)
{
ElemType ch;
cin >> ch;
if (ch == '#')
t = NULL;//此树为空树,不再对它递归生成左右子树结点
else
{
t = (BiTree)malloc(sizeof(BiTNode));
if (!t)
exit(OVERFLOW);
t->data = ch;//对结点元素赋值
CreateBiTree(t->lchild);//递归生成左子树
CreateBiTree(t->rchild);//递归生成右子树
}
return OK;
}
先(根)序遍历:访问根结点,先序遍历左子树,先序遍历右子树
中(根)序遍历:中序遍历左子树,访问根结点,中序遍历右子树
后(根)序遍历:后序遍历左子树,后序遍历右子树,访问根结点
/*先序遍历*/
void PreOrderTraverse(BiTree t, Status(*visit)(ElemType))
{
if (t)
{
visit(t->data);//输出结点元素
PreOrderTraverse(t->lchild, visit);//先序遍历左子树
PreOrderTraverse(t->rchild, visit);//先序遍历右子树
}
}
/*中序遍历*/
void InOrderTraverse(BiTree t, Status(*visit)(ElemType))
{
if (t)
{
InOrderTraverse(t->lchild, visit);//中序遍历左子树
visit(t->data);//输出结点元素
InOrderTraverse(t->rchild, visit);//中序遍历右子树
}
}
/*后序遍历*/
void PostOrderTraverse(BiTree t, Status(*visit)(ElemType))
{
if (t)
{
PostOrderTraverse(t->lchild, visit);//后序遍历左子树
PostOrderTraverse(t->rchild, visit);//后序遍历右子树
visit(t->data);//输出结点元素
}
}
/*输出函数*/
Status print(ElemType e)
{
cout << e;
return OK;
}
深度递归求法:分别通过递归调用获得某结点的左右子树最大深度,该结点的深度既为左右子树最大深度+1,类推根结点可以得到树的深度大小。
int depth(BiTree t)
{
int depthl, depthr;
if (!t)
return 0;
depthl = depth(t->lchild);//递归遍历左子树,求得所在结点左子树的最大深度
depthr = depth(t->rchild);//递归遍历右子树,求得所在结点右子树的最大深度
return (depthl > depthr ? depthl : depthr) + 1;//返回该结点左右子树最大深度值+1
}
判断俩个二叉树是否相同:先判断所在结点是否为空,元素的值是否相同,然后先序遍历左右子树
Status Equal(BiTree t1, BiTree t2)
{
if (t1 == NULL&&t2 == NULL)//如果两个结点都为空,则相同
return TRUE;
else if (t1 == NULL || t2 == NULL)//如果一个为空,另一个不为空,则不同
return FALSE;
else
{
if (t1->data == t2->data)//如果两个结点的元素相同
if (Equal(t1->lchild, t2->lchild))//判断两个结点的左子树
if (Equal(t1->lchild, t2->rchild))//判断两个结点的右子树
return TRUE;
return FALSE;
}
}
删除结点及其子孙结点:先序遍历寻找元素对应结点,后序遍历释放子孙结点,对应结点指向空域
void DelSubTree(BiTree t)
{
if (t)//结点不空
{
DelSubTree(t->lchild);//遍历该结点左子树
DelSubTree(t->rchild);//遍历该结点右子树
free(t);//释放结点空间
}
}
void DelTree(BiTree &t, ElemType x)
{
if (t)
{
if (t->data == x)//找到想要删除的结点
{
DelSubTree(t);//释放该结点和其子孙结点的空间
t = NULL;//该结点指NULL
}
else
{
DelTree(t->lchild,x);//遍历左子树寻找对应结点
DelTree(t->rchild,x);//遍历右子树寻找对应结点
}
}
}
返回二叉树先序序列第k个结点的值: 先序遍历寻找该结点,然后输出元素
BiTree count_k(BiTree t, int &k)
{
BiTree p;
if (!t || k <= 0)//结点为空或者没有该序号,输出空
return NULL;
k--;
if (k == 0)//k==0,则为该结点
return t;
if (p = count_k(t->lchild, k))//遍历左子树寻找该结点
return p;
else//遍历右子树寻找该结点
return count_k(t->rchild, k);
}
Status Loc_k(BiTree t, int k, ElemType &e)
{
BiTree p;
p = count_k(t, k);
if (p)
{
e = p->data;
return OK;
}
else
return ERROR;
}