目录
层次遍历
1,寻找公共祖先
已知一棵二叉树按顺序存储结构进行存储,求编号分别为i和j的两个结点的最近的公共祖先的结点的值。
算法:采用递归的方法。
操作过程:
1、最差的结果是最近的公共祖先的结点是根结点,此时i和j分别在左右树。
2、 一直往上找,找i的祖先和j的祖先。并分别将祖先赋名给i和j。
当i = j时,i和j是一个结点,则说明找到了公共祖先。
Elemtype Comm_Ancestor(SqTree T, int i, int j)
{
if (T[i] != '#' && T[j] != '#')
{
//假设#是该结点不存在。
while (i != j)
{
if (i > j)
{
//i>j时可能i是j的下一层结点(有可能是孩子,也可能不是)
//可能是右(堂)兄弟
i = i / 2;
}
else
{
j = j / 2;
}
return T[i];
}
}
}
2,二叉树的遍历
时间复杂度都是O(n)
先序遍历 (NLR)
特点:根左右
操作过程:
1:若二叉树为空,则什么也不做;
2:访问根结点,接下来先序遍历左子树,先序遍历右子树。
对于左子树和右子树同样进行先序遍历。
算法:递归
void PreOrder(BiTree T)
{
if (T != NULL)
{
visit(T); //访问根结点
PreOrder (T -> lchild);//访问左子树
PreOrder (T -> rchild);//访问右子树
}
}
特点:根左右
操作过程:
1:若二叉树为空,则什么也不做;
2:访问根结点,接下来先序遍历左子树,先序遍历右子树。
对于左子树和右子树同样进行先序遍历。
算法:借助栈
void PreOrder2(BiTree T)
{
//初始化栈S,p是遍历指针。
InitStack(S);
BiTree p = T;
//栈不空或P不空时循环
while (p || !IsEmpty(S))
{
if (p)
{
//一路向左
visit(p);
Push(S,p);//访问当前结点,并入栈
p = p -> lchild;//左孩子不空,一直向左走
}
else
{
//出栈,并转向出栈结点的右子树
Pop(S,p);//栈顶元素出栈
p = p -> rchild;//向右子树走,p赋值为当前结点的右孩子
}
//返回while循环继续继续进入if-else语句。
}
}
中序遍历(LNR)
特点:左根右
操作过程:
1:若二叉树为空,则什么也不做;
2:中序遍历左子树,访问根结点,中序遍历右子树。
算法:递归
void InOrder(BiTree T)
{
if (T != NULL)
{
InOrder(T -> lchild); //遍历递归左子树
visit(T); //访问根结点
InOrder (T -> rchild);//遍历递归右子树
}
}
特点:左根右
操作过程:
1:若二叉树为空,则什么也不做;
2:中序遍历左子树,访问根结点,中序遍历右子树。
算法:借助栈
void InOrder2(BiTree T)
{
//初始化栈S,p是遍历指针。
InitStack(S);
BiTree p = T;
//栈不空或P不空时循环
while (p || !IsEmpty(S))
{
if (p)
{
//一路向左
Push(S,p);//当前结点入栈
p = p -> lchild;//左孩子不空,一直向左走。
}
else
{
//出栈,并转向出栈结点的右子树
Pop(S,p);
visit(p);//栈顶元素出栈,访问出栈结点
p = p -> rchild;//向右子树走,p赋值为当前结点的右孩子
}
//返回while循环继续继续进入if-else语句。
}
}
后序遍历(LRN)
特点:左右根
操作过程:
1:若二叉树为空,则什么也不做;
2:后序遍历左子树,后序遍历右子树,访问根结点。
算法:递归
void PostOrder(BiTree T)
{
if (T != NULL)
{
PostOrder(T -> lchild); //遍历递归左子树
PostOrder (T -> rchild);//遍历递归右子树
visit(T); //访问根结点
}
}
层次遍历
借助队列
void levelOrder(BiTree T)
{
InitQuene(Q);//初始化辅助队列
BiTree p;
EnQuene(Q,T);//将根结点入队
while (!IsEmpty(Q))
{
//队列不空循环
DeQuene(O,p);//队头结点出队
visit(p);//访问出队结点
if (p -> lchild != NULL)
{
EnQuene(Q,p -> lchild);//左子树不空,则左子树根结点入队
}
if (p -> rchild != NULL)
{
EnQuene(Q,p -> rchild);//右子树不空,则右子树根结点入队
}
}
}