遍历是树结构算法中的重要部分,前面发了有关递归遍历的内容,要知道:递归就是函数调用函数本身,运行起来就是函数嵌套函数,层层嵌套,所以函数调用、参数堆栈都是不小的开销,但是程序简单。然而,非递归即不断地对参数入栈、出栈,省去了函数层层展开、层层调用的开销。虽然参数出入栈次数多了,但是一般都开辟固定的足够大的内存来一次性开辟、重复使用。
目录
一、 先序遍历(非递归)
遍历步骤
直接上代码
二、 中序遍历(非递归)
遍历步骤
直接上代码
三、 后序遍历(非递归)
遍历步骤
直接上代码
一、 先序遍历(非递归)
遍历步骤
先序遍历的最终访问次序是:根 - 左 - 右 ,具体步骤如下:
1. 设有一棵如下结构的树,并申请一个栈stack,用于存放树结点;
2. 将根节点'1'(如果有的话)入栈;
注:入栈时 先右后左
while(stack不为空){
从栈中弹出一个栈顶元素root;
访问该结点root;(本例中将此添加到res数组中)
if (root结点有右儿子)
将右儿子结点入栈;
if (root结点有左儿子)
将左儿子结点入栈;
}
stack栈为空,循环结束,先序遍历完毕!
直接上代码
// 非递归先序遍历:
public void PreOrderTraversalNoRecursive(TreeNode root){
if (root != null) {
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
while(!stack.isEmpty()) {
root = stack.pop();
Vist(root);
if(root.Rchild != null) {
stack.push(root.Rchild);
}
if(root.Lchild != null) {
stack.push(root.Lchild);
}
}
}
}
二、 中序遍历(非递归)
遍历步骤
中序遍历的最终访问次序是:左 - 根 - 右 ,具体步骤如下:
1. 设有一棵如下结构的树,并申请一个栈stack,用于存放树结点;
2. 以下操作为一个循环,
while(stack不为空 ){
if (当前结点head不为空) :
head结点入栈; head = head.left;
else:
head = 栈顶出栈;
访问该结点head;(本例中将此添加到res数组中)
head = head.right;
}
stack1栈为空,循环结束,中序遍历完毕!
直接上代码
// 非递归中序遍历:
public void InOrderTraversalNoRecursive(TreeNode head){
if (head != null) {
Stack<TreeNode> stack = new Stack<>();
while(!stack.isEmpty() || head!=null) {
if(head != null) {
stack.push(head);
head = head.Lchild;
}else {
head = stack.pop();
Vist(head);
head = head.Rchild;
}
}
}
}
三、 后序遍历(非递归)
遍历步骤
后序遍历的最终访问次序是:左 - 右 - 根 ,具体步骤如下:
1. 设有一棵如下结构的树,并申请两个栈s1用于临时存放树结点、s2_res用于存放最终结点序列;
2. 将根节点'1'(如果有的话)入栈;
注:s1入栈时 先左后右
while(stack不为空) {
从栈中弹出一个栈顶元素root;
访问该结点root;(本例中将此压入到s2_res栈中)
if (root结点有左儿子)
将左儿子结点入栈;
if (root结点有右儿子)
将右儿子结点入栈;
}
最后将s2所有结点出栈:4 ,5 ,2 ,6 ,7 ,3 ,1 ; 即为后序遍历序列。
直接上代码
// 非递归后序遍历:
public void PostOrderTraversalNoRecursive(TreeNode root){
if (root != null) {
Stack<TreeNode> s1 = new Stack<>();// 操作栈
Stack<TreeNode> s2 = new Stack<>();// 收集栈
s1.add(root);
while(!s1.isEmpty()) {
root = s1.pop();
s2.push(root);
if(root.Lchild != null) {
s1.push(root.Lchild);
}
if(root.Rchild != null) {
s1.push(root.Rchild);
}
}
while(!s2.isEmpty()) {
Vist(s2.pop());
}
}
}