本文要点:
二叉树三种遍历方式(前序、中序、后序)的非递归实现
ps:递归方法实现:递归法实现二叉树的创建与遍历
非递归的实现需要借助栈!!
前序:
首先需要判断是否是空树,是空返回;否则从根部一直向树的左子树方遍历,遍历一个访问一个,并且将其压入栈。当树不为空,并且栈不为空时,说明栈里仍有元素可访问。
void _PrevOrder_NonR(Node* root) //非递归--前序 { if(root == NULL) return ; Node* cur = root; stack<Node*> s; while (cur || !s.empty()) //cur != NULL说明仍然有子树可以被遍历 //!s.empty() 说明栈不为空时可以有数据被访问 { while (cur) { cout<<cur->_data<<" "; s.push(cur); cur = cur->_left; } Node* top = s.top(); s.pop(); cur = top->_right; //访问当前根节点的右子树 } cout<<endl; } 中序:
中序的过程与前序相似,只是访问数据的时间不同。中序是先入栈再访问,即当左子树入栈以后才访问
void _InOrder_N0nR(Node* root) //非递归--中序 { if(root == NULL) return ; Node* cur = root; stack<Node*> s; while(cur || !s.empty()) { while(cur) { s.push(cur); cur = cur->_left; } Node* top = s.top(); //此时栈顶存的是当前子树的根节点 cout<<top->_data<<" "; s.pop(); cur = top->_right; //将右子树作为左子树的子树来遍历 } cout<<endl; } 后序:三种非递归遍历中,后序遍历是比较难理解的。后序遍历必须保证左子树和右子树都访问完以后才能访问根节点,而能访问根节点的可能是有两种:右子树已经被访问或者当前根节点的右子树为NULL。因此,就需要一个标记位pos,当当前根节点右子树和pos相等时,说明已经可以访问该根节点了。
void _PostOrder_NonR(Node* root) //非递归--后序 { Node* cur = root; Node* pos = root; stack<Node*> s; while (cur || !s.empty()) { while (cur) { s.push(cur); cur = cur->_left; } Node* top = s.top(); if (top->_right == NULL || top->_right == pos) //top存的是当前的根节点,当top的右子树为空或者top的右子树为pos,说明右子树已经遍历过, //这时就可以访问当前的根节点了 { cout<<top->_data<<" "; pos = top; s.pop(); } else { cur = top->_right; } } cout<<endl; }