王道数据结构 (9) 树的中序遍历非递归代码实现
代码实现 :
#include <stdio.h> #include <string.h> #include <stdlib.h> #define ElementType char int top = -1; //定义top栈顶元素下标 // 结点结构体 typedef struct BinTNode{ ElementType data; struct BinTNode * left; struct BinTNode * right; }BinTNode, *BinTree; // 初始化树形结构 BinTNode * CreateBiTree(BinTNode *T) { T=(BinTNode*)malloc(sizeof(BinTNode)); T->data='A'; T->left=(BinTNode*)malloc(sizeof(BinTNode)); T->left->data='B'; T->right=(BinTNode*)malloc(sizeof(BinTNode)); T->right->data='C'; T->left->left=(BinTNode*)malloc(sizeof(BinTNode)); T->left->left->data='D'; T->left->right=(BinTNode*)malloc(sizeof(BinTNode)); T->left->right->data='E'; T->left->right->left=NULL; T->left->right->right=NULL; T->left->left->left=(BinTNode*)malloc(sizeof(BinTNode)); T->left->left->left->data='H'; T->left->left->left->left=NULL; T->left->left->left->right=NULL; T->left->left->right=(BinTNode*)malloc(sizeof(BinTNode)); T->left->left->right->data='I'; T->left->left->right->left=NULL; T->left->left->right->right=NULL; T->right->left=(BinTNode*)malloc(sizeof(BinTNode)); T->right->left->data='F'; T->right->left->left=NULL; T->right->left->right=NULL; T->right->right=(BinTNode*)malloc(sizeof(BinTNode)); T->right->right->data='G'; T->right->right->left=NULL; T->right->right->right=NULL; return T; } // 栈 - 进栈push void push(BinTNode** stack,BinTNode * elem) { stack[++top] = elem; } //栈 - 弹栈pop void pop(){ if (top == -1) { return ; } top--; } // 遍历过程中,输出结点值 void printElement(BinTNode* elem) { printf("%c ",elem->data); } //获取栈顶元素 BinTNode* getTop(BinTNode** stack){ return stack[top]; } //非递归遍历 - 左根右 void InOrderTraverse(BinTNode * Tree) { BinTNode * stack[20]; // 定义一个栈 BinTNode * p = Tree; // 定义临时指针 // 1 当前指针指向不为NULL - 说明有右孩子 // 2 或者栈内不空 - 说明该指针处没有右孩子,继续弹出结点值 while (p || top!=-1) {
if (top!=-1) {
p=getTop(stack); //取栈顶元素 pop(); //栈顶元素弹栈 printElement(p); p = p->right; } } } int main() { BinTNode * Tree; Tree = CreateBiTree(Tree); printf("中序遍历:\t"); InOrderTraverse(Tree); printf("\n"); return 0; }
1.沿着跟节点依次进栈直到左节点为空
while (p){ push(stack, p); // 循环将左孩子进栈 p = p->left; }
将左边的节点 依次进栈
A B D H
此刻栈中的顺序是这样的 :
2.栈顶元素出栈 并且输出 如果其孩子节点为空 再执行第2 步 如果不为空执行 第一步
(1)H 是 栈顶 元素 先出栈 右孩子节点 木有 并且栈中有元素 继续执行第2 步
(2)D是栈顶元素 先出栈 右孩子节点为 i, 先进栈 I 木有左孩子节点 跳出循环
(3)I 是栈顶元素 I木有右节点 出栈
(4)B 是栈顶元素 B有右节点E 将右节点 E进栈
(5) E 是栈顶元素 E出栈 E木有右节点
(6) A 是栈顶元素 A有右节点 C C走 while (p) 循环 进栈 C 有左节点 F F进栈 F木有左边节点 跳出while 循环
(7)F是栈顶元素 出栈 木有右节点 继续循环 if(top!=-1)
(8) C是栈顶元素 出栈 C有右节点 G 跳出循环 G进栈 G木有左节点 跳出循环 走if 循环
(9) G是栈顶元素 G出栈 G木有右节点 跳出循环
(10)p 不存在 pop 为 - 1 整个循环结束
所以整个输出 就是 H D I B E A F C G
越努力越幸运