目录
二叉树的非递归办法
1.前序遍历
在遍历完整个左子树后如何找到该节点的右子树的根指针
解决办法:在访问完该节点后,将该节点的指针保存在栈中,以便以后能通过他找到该节点的右子树
大致的思路:
首先将root压入堆栈,之后在p不为空的时候
循环去遍历左子树,并且遇到的每一个左子树都输出,在把指针p保存在堆栈中
当左子树为空的时候,弹出栈顶元素,将p指向栈顶元素,然后再去访问
栈顶元素的右子树,并且输出,入栈。之后再去循环遍历左子树,并且将每一个左子树都输出。。。。
当栈为空而且p=NULL时,循环结束
前序遍历伪代码:
void BiTree::preOrder()
{
Stack s;
p=root;
while(!(p==NULL&&s.isempty()))
{
while(p!=NULL)
{
visit(p->data);
s.push(p);
p=p->lchild;
}
if(!s.isEmpty())//但是如果这里是空的话怎么办
{
p=p.pop();
p=p->rchild;
}
}
}
代码:
void BiTree::preorder()
{
if(root == NULL)
{
return;
}
stack<Element> s;
BiNode* p = root;
Element e;
while(p!=NULL || !s.empty())
{
while(p!=NULL)
{
cout << p->data;
e.ptr = p;
e.flag = 1;
s.push(e);
p = p->lchild;
}
if(!s.empty())
{
e = s.top();
s.pop();
p = e.ptr;
if(e.flag == 1)
{
e.flag = 2;
s.push(e);
p = p->rchild;
}
else if(e.flag==2)
{
p=NULL;
}
}
}
}
2.中序遍历
相同的思路
代码:
void BiTree::inOrder(){
//用非递归法中序遍历(临时建立堆栈)
stack<Element> s;
BiNode *p = root;
Element e;
while (p != NULL || !s.empty())
{
while (p != NULL) {
e.ptr = p;
e.flag = 1;
s.push(e);
p = p->lchild;
}
if (!s.empty()) {
e = s.top();
s.pop();
p = e.ptr;
if (e.flag == 1) {
cout << p->data;
e.flag = 2;
s.push(e);
p = p->rchild;
}
else if(e.flag==2)
p=NULL;
}
}
}
3.后序遍历
代码:
void BiTree::postOrder(){
//用非递归法后序遍历(临时建立堆栈)
stack<Element> s;
BiNode *p = root;
Element e;
while (p != NULL || !s.empty()) {
while (p != NULL) {
e.ptr = p;
e.flag = 1;
s.push(e);
p = p->lchild;
}
if (!s.empty()) {
e = s.top();
s.pop();
p = e.ptr;
if (e.flag == 1) {
e.flag = 2;
s.push(e);
p = p->rchild;
} else {
cout << p->data;
p = NULL; // 防止重复入栈
}
}
}
}
总代码:(以前序遍历为例)
/*
非递归遍历二叉树,前序遍历
*/
#include <stack>
#include <iostream>
using namespace std;
const int STACKSIZE=100; //定义栈最大值常量
const int QUEUESIZE = 100;
struct BiNode{
char data;
BiNode *lchild, *rchild;
};
typedef struct element{
BiNode *ptr;
int flag; //1表示第1次出栈,2表示第2次出栈
}Element;
class BiTree {
private:
BiNode *root; //指向根结点的头指针
public:
BiTree(){ //构造函数,建立一棵二叉树
root= NULL;
root = creat(root);
}
~BiTree(){
release(root);
}
void preOrder(); //前序遍历二叉树
private:
BiNode *creat(BiNode *bt); //构造函数调用
void release(BiNode *bt); //析构函数调用
};
BiNode *BiTree ::creat(BiNode *bt){
//用前序遍历法创建二叉树
char ch;
cin >> ch;//输入结点的数据信息,假设为字符
if (ch == '#') //建立一棵空树
bt = NULL;
else {
bt = new BiNode ;
bt->data = ch; //生成一个结点,数据域为ch
bt->lchild = creat(bt->lchild); //递归建立左子树
bt->rchild = creat(bt->rchild); //递归建立右子树
}
return bt;
}
/**后序释放二叉树节点*/
void BiTree::release(BiNode *bt){
if(bt==NULL)
{
return;
}
else
{
release(bt->lchild);
release(bt->rchild);
}
}
void BiTree::preOrder(){
{
if(root == NULL)
{
return;
}
stack<Element> s;
BiNode* p = root;
Element e;
while(p!=NULL || !s.empty())
{
while(p!=NULL)
{
cout << p->data;
e.ptr = p;
e.flag = 1;
s.push(e);
p = p->lchild;
}
if(!s.empty())
{
e = s.top();
s.pop();
p = e.ptr;
if(e.flag == 1)
{
e.flag = 2;
s.push(e);
p = p->rchild;
}
else if(e.flag==2)
{
p=NULL;
}
}
}
}
}
int main(){
BiTree tree;
cout << "NoRecursive PreOrder : ";
tree.preOrder();
return 0;
}