层次遍历
-
通过队列实现,从上往下一层一层去遍历,A?---->?B、C?---->?D、E、F?---->?G、H -
1.入队? ? 2.打印数据 -
A入队,打印:A? 队列中的元素:A? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 打印结果:A??? -
A出队?
-
B出队
-
C出队 . . . 把C的左子树和右子树入队,打印C的左子树和右子树 -
D出队 . . . 把D的左子树和右子树入队,打印D的左子树和右子树 -
当队列为 NULL,整个二叉树就打印出来了 -
测试代码:数据结构 --- c语言递归法遍历二叉树_考拉爱睡觉鸭~的博客-CSDN博客
//要遍历的树
void layerOrder(LPTREE root)
{
LPTREE pmove = root; //定义一个移动的节点==根节点
//准备一个队列--->存的是一个节点<->指针 定义的是一个指针,用数组充当队列的容器
LPTREE queue[1024];
int front = 0; //队头标记
int tail = 0; //队尾标记
queue[tail++] = pmove; //第一个节点入队 队尾做变化
printf("%c", pmove->data); //打印第一个节点的数据
while (front != tail) //队列不为空出队
{
pmove = queue[front++]; //出队 队头做变化 出队后把左、右子树入队
if (pmove->LChild != NULL) //左边!=NULL 左子树入队
{
queue[tail++] = pmove->LChild; //队尾做变化 1.入队 2.打印数据
printf("%c", pmove->LChild->data);
}
if (pmove->RChild != NULL) //右边!=NULL 右子树入队
{
queue[tail++] = pmove->RChild;
printf("%c", pmove->RChild->data);
}
}
}
int main()
{
//创建二叉树--->无序的树--->创建节点
LPTREE A = createNode('A'); //A节点
LPTREE B = createNode('B');
LPTREE C = createNode('C');
LPTREE D = createNode('D');
LPTREE E = createNode('E');
LPTREE F = createNode('F');
LPTREE G = createNode('G');
LPTREE H = createNode('H');
//一个个连接
insertNode(A, B, C); //A下面插入B、C
insertNode(B, D, E); //B下面插入D、E
insertNode(E, G, NULL);
insertNode(C, NULL, F);
insertNode(F, H, NULL);
//打印结果
layerOrder(A); //ABCDEFGH
printf("\n");
return 0;
}
前序、中序、后序的非递归法遍历?
前序遍历 根左右
//非递归法先序
void preOrderByStack(LPTREE root)
{
if (root == NULL) //为空无法打印
return;
LPTREE pmove = root; //定义移动的指针==根节点
//栈
LPTREE stack[1024]; //准备栈存储节点的位置<->指针
int stackTop = -1; //栈顶标记
while (stackTop != -1 || pmove) //pmove!=NULL
{
//先走左边,边打印边入栈
while (pmove != NULL)
{
printf("%c", pmove->data); //打印数据
stack[++stackTop] = pmove; //入栈 栈顶标记从-1开始 ++栈顶标记
pmove = pmove->LChild; //入栈后一直往左边走,直到走到空的位置
}
//退出循环,到达空的位置,出栈找右边
if (stackTop != -1) //栈为空无法出栈
{
pmove = stack[stackTop--];
pmove = pmove->RChild; //找 出栈后节点的右边
}
}
}
?中序遍历??左根右
- 刚开始只做入栈操作,不做数据打印,先走到树的最左边
- 在出栈的位置打印,先走完再做打印
//非递归法中序
void midOrderByStack(LPTREE root)
{
if (root == NULL)
return;
LPTREE pmove = root;
//栈
LPTREE stack[1024];
int stackTop = -1;
while (pmove != NULL || stackTop != -1)
{
while (pmove) //pmove!=NULL
{
stack[++stackTop] = pmove; //入栈
pmove = pmove->LChild; //pmove一直往左边走 走到最左边
}
//退出循环,到达空的位置
if (stackTop != -1) //栈不为空出栈
{
pmove = stack[stackTop--];
printf("%c", pmove->data); //打印数据
pmove = pmove->RChild; //找 出栈后节点的右边
}
}
}
?后序遍历 左右根
//非递归法后序
void lastOrderByStack(LPTREE root)
{
if (root == NULL)
return;
LPTREE pmove = root;
//栈
LPTREE stack[1024];
int stackTop = -1;
//1.先走到最左边
while (pmove)
{
stack[++stackTop] = pmove; //pmove!=NULL一直走到最左边 持续入栈
pmove = pmove->LChild;
}
LPTREE lastvisited = NULL; //记录被访问的节点<->访问标记
while (stackTop != -1) //栈不为空做出栈操作
{
pmove = stack[stackTop--]; //出栈
//右边没有节点或者被访问了一次-->走过一次了在做回退
if (pmove->RChild == NULL || pmove->RChild == lastvisited)
{
printf("%c", pmove->data);
lastvisited = pmove; //改变上一次访问的标记==当前遍历的节点
}
else //有右边就要走右边
{
stack[++stackTop] = pmove; //当前节点入栈
pmove = pmove->RChild; //往当前节点右边走
while (pmove)
{
stack[++stackTop] = pmove; //右子树的左边走到底
pmove = pmove->LChild;
}
}
}
}
?测试代码
int main()
{
//创建二叉树--->无序的树--->创建节点
LPTREE A = createNode('A'); //A节点
LPTREE B = createNode('B');
LPTREE C = createNode('C');
LPTREE D = createNode('D');
LPTREE E = createNode('E');
LPTREE F = createNode('F');
LPTREE G = createNode('G');
LPTREE H = createNode('H');
//一个个连接
insertNode(A, B, C); //A下面插入B、C
insertNode(B, D, E); //B下面插入D、E
insertNode(E, G, NULL);
insertNode(C, NULL, F);
insertNode(F, H, NULL);
preOrderByStack(A); //ABDEGCFH
printf("\n");
midOrderByStack(A); //DBGEACHF
printf("\n");
lastOrderByStack(A); //DGEBHFCA
printf("\n");
}
|