本文是MOOC浙大数据结构课程的笔记
课程详细地址
遍历过程:
void InOrderTraversal(BinTree BT)
{
if (BT) {
printf("%d", BT->Data);
InOrderTraversal(BT->Left);
InOrderTraversal(BT->Right);
}
}
非递归遍历算法
使用堆栈
void InOrderTraversal(BinTree BT)
{
BinTree T = BT;
Stack S = CreatStack(MaxSize); //创建初始化堆栈s
while (T || !IsEmpty(s)) {
while (T) {// 一直向左并且将沿途的结点压入堆栈
Push(S, T);
printf("%5d", T->Data);// 打印结点
T = T->Left;
}
if (!IsEmpty(s)) {
T = Pop(s); // 结点弹出堆栈
T = T->Right;// 转向右子树
}
}
}
遍历过程:
void InOrderTraversal(BinTree BT)
{
if (BT) {
InOrderTraversal(BT->Left);
printf("%d", BT->Data);
InOrderTraversal(BT->Right);
}
}
非递归遍历算法
使用堆栈
void InOrderTraversal(BinTree BT)
{
BinTree T = BT;
Stack S = CreatStack(MaxSize); //创建初始化堆栈s
while (T || !IsEmpty(s)) {
while (T) {// 一直向左并且将沿途的结点压入堆栈
Push(S, T);
T = T->Left;
}
if (!IsEmpty(s)) {
T = Pop(s); // 结点弹出堆栈
printf("%5d", T->Data);// 打印结点
T = T->Right;// 转向右子树
}
}
}
遍历过程:
void InOrderTraversal(BinTree BT)
{
if (BT) {
InOrderTraversal(BT->Left);
InOrderTraversal(BT->Right);
printf("%d", BT->Data);
}
}
非递归遍历算法
使用堆栈
后序遍历也可以使用非递归遍历算法来实现,但不能像前序和中序一样简单的调一下输出语句就可以实现,因为后序遍历需要先访问完左右结点才输出根节点。
需要在结构中定义个标识
void InOrderTraversal(BinTree BT)
{
BinTree T = BT;
Stack S = CreatStack(MaxSize); //创建初始化堆栈s
while (T || !IsEmpty(s)) {
while (T) {// 一直向左并且将沿途的结点压入堆栈
Push(S, T);
T->Tag=1;// 标记为1
T = T->Left;
}
if (!IsEmpty(s)) {
T = Pop(s); // 结点弹出堆栈
if(T->Tag=1){
(T->Tag)++;
printf("%5d", T->Data);// 打印结点
T = T->Right;// 转向右子树
}else{
printf("%5d", T->Data);// 打印结点
}
}
}
}
二叉树遍历的核心问题:二维结构的线性化
所以需要一个存储结构来保存暂时不访问的结点,可以用堆栈、队列来存储
队列实现:
遍历从根结点开始,首先将根结点入队,然后开始执行循环:结点出队、访问该结点、其左右儿子入队
遍历过程:
先根节点入队,然后:
void LevelOrderTraversal(BinTree BT)
{
Queue Q;BinTree T;
if(!BT)return; // 空树直接返回
Q=CreatQueue(MaxSize); // 创建队列
AddQ(Q,BT);
while(!IsEmptyQ(Q)){
T=DeleteQ(Q);
printf("%d\n",T->Data);
if(T->Left)AddQ(Q,T->Left);
if(T->Right)AddQ(Q,T->Right);
}
}
如果将层序遍历中的队列改为堆栈,是否也是一种树的遍历?可以应用这种方法改造出一种前序、中序、后序的非递归遍历吗?
上文已有解答。
void PreOrderPrintLeaves(BinTree BT)
{
if (BT) {
if(!BT->Left && !BT->Right)
printf("%d", BT->Data);
InOrderTraversal(BT->Left);
InOrderTraversal(BT->Right);
}
}
只要知道了左右子树的高度就可以知道二叉树的高度
void PostOrderGetHeight(BinTree BT)
{
int HL,HR,MaxH;
if (BT) {
HL=PostOrderGetHeight(BT->Left);
HR=PostOrderGetHeight(BT->Right);
MaxH=(HL>HR)?HL:HR;
return (MaxH+1);
}
else return 0;
}
一定要有中序,没有中序会产生左右判断的问题
先序和中序遍历序列来确定一颗二叉树