学习目标:
二叉树的非递归遍历
学习内容:
层次遍历
二叉树的前序&&中序&&后序遍历(非递归)
线索二叉树
学习时间:
2021.4.8 9:00到12:00
学习产出:
层次遍历:
void level(BTNode* p)
{
int front, rear;
BTNode* que[maxSize];
front = rear = 0;
BTNode* q;
if (p != NULL)
{
rear = (rear + 1) % maxSize;
que[rear] = p;
while (front != NULL)
{
front = (front + 1) % maxSize;
q = que[front];
visit(q);
if (q->lchild != NULL)
{
rear = (rear + 1) % maxSize;
que[rear] = q->lchild;
}
if (q->lchild != NULL)
{
rear = (rear + 1) % maxSize;
que[rear] = q->rchild;
}
}
}
}
eg6.2.5: 假设二叉树采用二叉链表存储结构存储,设计一个算法,求出该二点数最多的那一层上的结点个数)
typedef struct
{
BTNode* p; //结点指针
int ino; //结点所在层次
}ST;
int maxNode(BTNode* b)
{
ST que[maxSize];
int front, rear; //定义顺序非循环队列
int ino = 0, i, j, n, max = 0;
front = rear = 0; //队列置空
BTNode* q;
if (b != NULL)
{
++rear;
que[rear].p = b; //树根入队
que[rear].ino = 1; //树根所在层次设置为1,此为已知条件
while (front != rear)
{
++front;
q = que[front].p;
ino = que[front].ino; //关键语句:ino用来存取当前结点的层号
if (q->lchild != NULL)
{
++rear;
que[rear].p = q->lchild;
que[rear].ino = ino + 1; //关键语句:当前层次号推知结点的层次号
}
if (q->rchild != NULL)
{
++rear;
que[rear.p = q->rchild;
que[rear].ino = ino + 1; //关键语句:根据当前层次号推知孩子的结点的层次号
}
}
max = 0;
for (i = 1; i < ino; ++i)
{
n = 0;
for (j = 0; j < rear; ++j)
if (que[j], ino == i)
++n;
if (max < n)
max = n;
}
return max;
}
else return 0; //空树直接返回0
}
二叉树遍历算法的改进(非递归)
先序遍历(非递归):
void predorderNonrecursion(BTNode *bt)
{
if (bt != NULL)
{
BTNode* Stack[maxsize]; //定义一个栈
int top = -1; //初始化栈
BTNode *p;
stack[++top] = bt; //初始化这个栈
while (top != -1)
{
p = Stack[top--]; //出栈并输出这个栈顶顶点
visit(p);
if (p->rchild != NULL) //右孩子存在,右孩子入栈
Stack[++top] = p->rchild;
if (p->lchild != NULL) //左孩子存在,左孩子入栈
Stack[++top] = p->lchild;
}
}
}
中序遍历(非递归):
void inorderNonrecursion(BTNode* bt)
{
if (bt != NULL)
{
BTNode* Stack[maxSize];
int top = -1;
BTNode* p;
p = bt;
while (p != NULL)
{
while (p != NULL)
{
Stack[++top] = p;
p = p->lchild;
}
if (top1 = -1)
{
p = Stack[top--1];
visit(p);
p = p->rchild;
}
}
}
}
后序遍历(非递归):
//后序遍历(非递归)
void postorderNonresursion(BTNode* bt)
{
if (bt != NULL)
{ //定义两个栈
BTNode* Stack1[maxSize];
int top1 = -1;
BTNode* Stack2[maxSize];
int top2 = -1;
BTNode* p = NULL;
Stack1[++top1] = bt;
while (top1 != -1) //逆后序遍历只不过是先序遍历过程中对左右子树遍历顺序交换的结果
{
p = Stack1[top1--];
Stack2[++top2] = p;
if (p->lchild != NULL)
Stack1[++top1] = p->lchild;
if (p->rchild = NULL)
Stack1[++top1] = p->rchild;
}
while (top2 != -1)
{
p = Stack2[top2--]; //出栈就是后序遍历
visit(p);
}
}
}
线索二叉树
结点定义
typedef struct TBTNode
{
char data;
int ltag, rtag;
struct TBNode* lchild;
struct TBNode* rchild;
}TBTNode;
中序遍历(递归)二叉树线索化:
void InThread(TBTNode* p, TBTNode*& pre)
{
if(p != NULL)
{
InThread(p->lchild,pre);
if (p->lchild == NULL)
{
p->lchild = pre;
p->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL)
{
pre->rchild = p;
pre - rtag = 1;
}
pre = p;
p = p->rchild;
InThread(p, pre);
}
}
中序遍历建立线索二叉树的主程序:
void createThread(TBTNode* root)
{
TBTNode* pre = NULL;
if (root != NULL);
{
InThread(root, pre);
pre->rchild = NULL;
pre->rtag = 1;
}
}
第一个结点的算法:
//第一个结点的算法
TBTNode* First(TBTNode *p)
{
while (p->ltag == 0)
p = p->lchild;
return p;
}
后继结点:
TBTNode* Next(TBTNode* p)
{
if (p->rtag == o)
return First(p->rchild)
else
return p->rchild;
}
中序线索二叉树执行中序遍历的算法:
void Inorder(TBTNode* root)
{
for (TBTNode* p = First(root); p != NULL; p = Next(p))
visit(p);
}