原理
1. 前序遍历
对于 先 序 遍历 非 递归 算法, 这里 我们 使用 一个 栈( stack) 来临 时 存储 节点, 方法 如下。
(1) 打印 根 节点 数据。
(2) 把 根 节点 的 right 入栈, 遍历 左 子 树。
(3) 遍历 完 左 子 树 返回 时, 栈 顶 元素 应为 right, 出 栈, 遍历 以该 指针 为 根 的 子 树。
2. 中序遍历
对 于中 序 遍历 非 递归 算法, 这里 使用 一个 栈( stack) 来临 时 存储 节点, 方法 如下。
(1) 先 将 根 节点 入栈, 遍历 左 子 树。
(2) 遍历 完 左 子 树 返回 时, 栈 顶 元素 应为 根 节点, 此 时出 栈, 并 打印 节点 数据。
(3) 再 中 序 遍历 右 子 树。
3. 后续遍历
现在 说明 对于 后序 遍历 的 非 递归 方法。 假设 T 是要 遍历 树 的 根 指针, 后序 遍历 要求 在 遍历 完 左、 右 子 树 后再 访问 根。 需要 判断 根 结点 的 左、 右 子 树 是否 均 遍历 过。
可采用 标记 法, 结点 入栈 时, 配 一个 标志 tag 一同 入栈( tag 为 0 表示 遍历 左 子 树 前 的 现场 保护, tag 为 1 表示 遍历 右 子 树 前 的 现场 保护)。
首先 将 T 和 tag( 为 0) 入栈, 遍历 左 子 树; 返回 后, 修改 栈 顶 tag 为 1, 遍历 右 子 树; 最后 访问 根 结点。
代码实现
int TraverseTreeInOrderUnrec(st_trNode * root){
st_dataNode * s = NULL;
st_trNode * p = root;
st_stack * stack = createStack();
while(NULL != p || !isStackEmpty(stack)){
/* 1. 左子树*/
while(NULL != p){
pushStack(stack, p->data);
p = p->left;
}
if(!isStackEmpty(stack)){
/* 2. 打印*/
s = popStack(stack);
printf(" %d ", s->data);
/* 3. 右子树 */
/*
* 如果stack可以保存树节点,可以不用这步,
* 主要用来查找到p后寻找p的子树的关系
*/
p = SearchBSTreeNode(root, s->data);
if(NULL != s){
free(s);
s = NULL;
}
p = p->right;
}
}
}
int TraverseTreePreOrderUnrec(st_trNode * root){
st_dataNode * s = NULL;
st_trNode * p = root;
st_stack * stack = createStack();
while(NULL != p || !isStackEmpty(stack)){
while(NULL != p){
/* 1. 打印*/
printf(" %d ", p->data);
/* 2. 左子树*/
pushStack(stack, p->data);
p = p->left;
}
if(!isStackEmpty(stack)){
s = popStack(stack);
/* 3. 右子树 */
/*
* 如果stack可以保存树节点,可以不用这步,
* 主要用来查找到p后寻找p的子树的关系
*/
p = SearchBSTreeNode(root, s->data);
if(NULL != s){
free(s);
s = NULL;
}
p = p->right;
}
}
}
int TraverseTreePostOrderUnrec(st_trNode * root){
st_dataNode * s = NULL;
st_trNode * p = root;
st_stack * stack = createStack();
while(NULL != p || !isStackEmpty(stack)){
while(NULL != p){
/* 1. 左子树*/
pushStack(stack, p->data);
p = p->left;
}
/*
* 结点 入栈 时, 配 一个 标志 tag 一同 入栈
*( tag 为 0 表示 遍历 左 子 树 前 的 现场 保护,
* tag 为 1 表示 遍历 右 子 树 前 的 现场 保护)。
* 首先 将 T 和 tag( 为 0) 入栈, 遍历 左 子 树;
* 返回 后, 修改 栈 顶 tag 为 1, 遍历 右 子 树;
* 最后 访问 根 结点。
*/
if(!isStackEmpty(stack)){
s = stack->top;
p = SearchBSTreeNode(root, s->data);
if(1 == p->tag){
/* 3. 打印 */
s = popStack(stack);
if(NULL != s){
free(s);
s = NULL;
}
printf(" %d ", p->data);
p->tag = 0;
p = NULL; /*第二次访问其右子树已经遍历*/
} else {
/*2. 右子树*/
p->tag = 1;
p = p->right;
}
}
}
}
代码编译
gcc main.c stack.c list.c tree.c -g -o a.exe -DDEBUG
调试输出
************ testBSTree ************
insert 5
1.1 root = 5
insert 3
1.6
1.2 left = 3, parent = 5
insert 7
1.7
1.5.1 root = 5
insert 2
1.7
1.4.2 root = 5, left = 3
1.6
1.2 left = 2, parent = 3
insert 4
1.7
1.4.2 root = 5, left = 3
1.7
1.5.1 root = 3
insert 6
1.7
1.5.2 root = 5, right = 7
1.6
1.2 left = 6, parent = 7
insert 8
1.7
1.5.2 root = 5, right = 7
1.7
1.5.1 root = 7
insert 1
1.7
1.4.2 root = 5, left = 3
1.7
1.4.2 root = 3, left = 2
1.6
1.2 left = 1, parent = 2
========= Dump Tree PreOder: 0x179a010 ===========
5 3 2 1 4 7 6 8
===================================
========= Dump Tree PreOder UnRec: 0x179a010 ===========
5 3 2 1 4 7 6 8
===================================
========= Dump Tree InOder: 0x179a010 ===========
1 2 3 4 5 6 7 8
===================================
========= Dump Tree InOderUnrec: 0x179a010 ===========
1 2 3 4 5 6 7 8
===================================
========= Dump Tree PostOrder: 0x179a010 ===========
1 2 4 3 6 8 7 5
===================================
========= Dump Tree PostOrder unRec: 0x179a010 ===========
1 2 4 3 6 8 7 5
===================================
node[0x179a030] = 5
Cannot find this node
node[0x179a150] = 8
mostLeft[0x179a180] = 1
mostLeft[0x179a120] = 6
========= Dump Tree PreOder: 0x179a010 ===========
7 6 3 2 1 4 8
===================================
========= Dump Tree PreOder UnRec: 0x179a010 ===========
7 6 3 2 1 4 8
===================================
========= Dump Tree InOder: 0x179a010 ===========
1 2 3 4 6 7 8
===================================
========= Dump Tree InOderUnrec: 0x179a010 ===========
1 2 3 4 6 7 8
===================================
========= Dump Tree PostOrder: 0x179a010 ===========
1 2 4 3 6 8 7
===================================
========= Dump Tree PostOrder unRec: 0x179a010 ===========
1 2 4 3 6 8 7
===================================