二叉排序树非递归遍历 -- C语言

原理

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
===================================
发布了194 篇原创文章 · 获赞 43 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/leoufung/article/details/104466626