二叉树 链式存储结构
结构定义:
template<typename ElemType>
struct BiNode
{
ElemType data;
struct BiNode* lchild, * rchild;
};
template<typename ElemType>
using BiTree = BiNode<ElemType>*;
基本操作:
遍历:二叉树最基本也最重要的操作,分成了前序遍历、中序遍历、后序遍历、层次遍历四种
- 前序遍历递归算法:首先访问根节点,然后遍历左子树、右子树;左右子树同样先遍历根节点,然后遍历左右子树,适合用递归解决
template<typename ElemType>
Status preOrderTraverse(BiTree<ElemType> T, Status(*visit)(BiTree<ElemType>&))//前序遍历 递归算法
{
//先遍历根节点,然后遍历左子树、右子树
if (T)
{
(*visit)(T);//遍历并访问根节点
preOrderTraverse(T->lchild, print);//前序遍历左子树
preOrderTraverse(T->rchild, print);//前序遍历右子树
return OK;
}//T为空表示当前子树遍历结束,可以退出当前递归
return ERROR;
}
- 中序遍历递归算法:首先遍历左子树,然后访问根节点,然后在访问右子树;左右子树同样也是按先访问左子树,然后根节点,最后右子树的顺序,适合用递归解决
template<typename ElemType>
Status inOrderTraverse(BiTree<ElemType> T, Status(*visit)(BiTree<ElemType>&))//中序遍历 递归算法
{
//先遍历左子树,然后遍历根节点,最后遍历右子树
if (T)
{
inOrderTraverse(T->lchild, print);//中序遍历左子树
(*visit)(T);//遍历并访问根节点
inOrderTraverse(T->rchild, print);//中序遍历右子树
return OK;
}//T为空表示当前子树遍历结束,可以退出当前递归
return ERROR;
}
- 中序遍历非递归算法:非递归算法需要借助栈来实现,每次都先访问最左边的节点,然后访问其根节点,再访问根节点的右子树
队列参考这里
template<typename ElemType>
Status inOrderTraverse_notRescure(BiTree<ElemType> T, Status(*visit)(BiTree<ElemType>&))//中序遍历 非递归算法
{
//每次都寻找最左边的节点进行访问,然后访问其右子树
BiTree<ElemType> t;
SqStack<BiTree<ElemType>> S;
initSqStsck(S);
push(S, T);
while (!isEmpty(S))
{
while (getTop(S, t) && t)//寻找最左端的节点
push(S, t->lchild);//将每个节点的左儿子入栈
//循环结束,表明已经到某个节点最左端,并且此时栈顶元素为空
pop(S, t);//弹出空指针
if (!isEmpty(S))//栈不空
{
pop(S, t);//弹出栈顶元素
(*visit)(t);//访问
push(S, t->rchild);//将栈顶元素右儿子入栈
}
}
return OK;
}
- 后序遍历递归算法:首先访问左右子树,然后访问根节点;对于左右子树同样也是先访问左右子树,再访问根节点,适合用递归解决
template<typename ElemType>
Status postOrderTraverse(BiTree<ElemType> T, Status(*visit)(BiTree<ElemType>&))//后序遍历 递归算法
{
//先访问左子树、右子树,最后访问根节点
if (T)
{
postOrderTraverse(T->lchild, print);//后序遍历左子树
postOrderTraverse(T->rchild, print);//后序遍历右子树
(*visit)(T)