二叉树的非递归遍历

来源:互联网 发布:尚学堂大数据百度网盘 编辑:程序博客网 时间:2024/06/07 02:00

能递归实现的一般都可以用栈来实现,因此可以用栈来实现二叉树的非递归遍历。以下图的二叉树为例:

1、先序遍历:首先把根结点入栈,然后根结点出栈(访问结点),在出栈的同时将其右左孩子进栈,再把栈顶元素出栈(访问结点),同时将其右左孩子入栈,如此反复知道栈为空。

typedef struct node{    int data;struct node *lchild,*rchild;}BTree;void PreOrderUnrec(BTree *root){if (NULL == root){return;}stack<BTree*> s;BTree *p;s.push(root);while (!s.empty()){p = s.top();Visit(p->data);s.pop();if (p->rchild != NULL){s.push(p->rchild);}if (p->lchild != NULL){s.push(p->lchild);}}}


还有另外一种方法:

(1)将二叉树的根结点作为当前结点;

(2)若当前结点非空,先访问该结点,并将该结点进栈,再将其左孩子结点作为当前结点,重复步骤(2),直到当前结点为空;

(3)若栈非空,则栈顶结点出栈,并将当前结点的右孩子在哦为当前结点;

(4)重复步骤(2)(3),直到栈为空且当前结点为空。

void PreOrderUnrec1(BTree *root){if (NULL == root){return;}stack<BTree*> s;BTree *p;p = root;while (p != NULL && !s.empty()){while (p != NULL){Visit(p->data);s.push(p);p = p->lchild;}if (!s.empty()){p = s.pop();p = p->rchild;}}}


 

2、中序遍历:

(1)将二叉树的根结点作为当前结点;

(2)如果当前结点非空,则该结点进栈并将其左孩子作为当前结点,重复步骤(2)直到当前结点为空;

(3)若栈非空,将栈顶结点出栈并访问,再将其右孩子作为当前结点;

(4)重复步骤(2)(3),直到栈为空且当前结点为空。

void MidOrderUnrec(BTree *root){if (NULL == root){return;}stack<BTree*> s;BTree *p;p = root;while (p != NULL || !s.empty()){while (p != NULL){s.push(p);p = p->lchild;}if (!s.empty()){p = s.pop();Visit(p->data);p = p->rchild;}}}


3、后序遍历:

后续遍历的非递归实现可以仿照先序遍历的第一种实现方法,和先序遍历不同的是,后序遍历不应该在出栈时才右左孩子进栈,而是应该在根父结点进栈的同时就把右左孩子入栈。在父结点出栈的时候,需要判断左右孩子是否已经遍历过,如果遍历过了才能遍历父结点。因此需要增加一个标志位来判断右左孩子是否遍历过,定义一个新的结构体

typedef struct STreeNode{BTree *treeNode;int flag;}*pSTree;

其中flag=0表示右左孩子没有遍历过,flag=2表示右左孩子已经遍历完。

void PostOrderUnrec(BTree *root){stack<pSTree> s;//根结点先入栈pSTree sTree = (pSTree)malloc(sizeof(struct STreeNode));sTree->treeNode = root;sTree->flag = 0;s.push(sTree);while (!s.empty()){pSTree p = s.pop;if (p->flag == 2)//如果栈顶结点标志位是2{Visit(p->treeNode->data);//则访问s.pop();}else{//如果右孩子存在,则进栈并将标志位加1if (p->treeNode->rchild){pSTree sTree = (pSTree)malloc(sizeof(struct STreeNode));sTree->treeNode = p->treeNode->rchild;sTree->flag = 0;s.push(sTree);}p->flag++;//如果左孩子存在,则进栈并将标志位加1if (p->treeNode->lchild){pSTree sTree = (pSTree)malloc(sizeof(struct STreeNode));sTree->treeNode = p->treeNode->lchild;sTree->flag = 0;s.push(sTree);}p->flag++;}}}


 

0 0