二叉树的非递归遍历

来源:互联网 发布:jdbc连接数据库5个步骤 编辑:程序博客网 时间:2024/06/05 17:45

首先,我们把二叉树看成,root,left,right。来分析如何实现非递归二叉树的前,中,后遍历。

前序遍历:
次序为:root,left,right。

//非递归前序遍历二叉树void preorder(NODE *t) {    if (t == NULL)  return;    stack<NODE *> s;    s.push(t);    while (!s.empty()) {        NODE *root = s.top();//赋值一份当前双亲节点        cout << root->data <<" ";        s.pop();        //先存储右子树,确保先输出左子树        if (root->rc)   s.push(root->rc);        //后存储左子树        if (root->lc)  s.push(root->lc);    }}

中序遍历:
次序为:left,root,right。

//非递归中序遍历二叉树void inorder(NODE *t) {    if (t == NULL) return;    NODE *root = t;    stack<NODE *>s;    while (root != NULL || !s.empty()) {        while (root != NULL) { //一路直走至左下角            s.push(root);            root = root->lc;        }        if (!s.empty()) {            root = s.top();//备份当前栈顶地址            s.pop();            cout << root->data << " ";            root = root->rc;        }    }}

后序遍历:
次序为:left,right,root。

//非递归后序遍历二叉树void postorder(NODE *t) {    if (t == NULL) return;    NODE *pr = NULL, *root = t;    stack<NODE *>s;    while (root != NULL || !s.empty()) {        while (root != NULL) { //一路直走至左下角            s.push(root);            root = root->lc;        }        root = s.top();        //右子树为空或者已访问,输出当前节点        if (root->rc == NULL || root->rc == pr) {            cout << root->data << ends;            pr = root;//将当前结点地址赋值rootre作为下一次判断标志,防止重复访问            s.pop();            root = NULL;//root赋值空以便访问右子树        } else {            root = root->rc;//访问子树的右子树        }    }}

完整代码 :

#include<iostream>#include<algorithm>#include<stack>using namespace std;typedef char A;typedef struct node{    A data;    struct node *lc,*rc;}NODE;NODE* buildtree(){    A a;    cin>>a;    if(a=='#')return NULL;    NODE *p = new node;    p->data = a;    p->lc = buildtree();    p->rc = buildtree();    return p; }//非递归前序遍历二叉树void preorder(NODE *t) {    if (t == NULL)  return;    stack<NODE *> s;    s.push(t);    while (!s.empty()) {        NODE *root = s.top();//赋值一份当前双亲节点        cout << root->data <<" ";        s.pop();        //先存储右子树,确保先输出左子树        if (root->rc)   s.push(root->rc);        //后存储左子树        if (root->lc)  s.push(root->lc);    }}//非递归中序遍历二叉树void inorder(NODE *t) {    if (t == NULL) return;    NODE *root = t;    stack<NODE *>s;    while (root != NULL || !s.empty()) {        while (root != NULL) { //一路直走至左下角            s.push(root);            root = root->lc;        }        if (!s.empty()) {            root = s.top();//备份当前栈顶地址            s.pop();            cout << root->data << " ";            root = root->rc;        }    }}//非递归后序遍历二叉树void postorder(NODE *t) {    if (t == NULL) return;    NODE *pr = NULL, *root = t;    stack<NODE *>s;    while (root != NULL || !s.empty()) {        while (root != NULL) { //一路直走至左下角            s.push(root);            root = root->lc;        }        root = s.top();        //右子树为空或者已访问,输出当前节点        if (root->rc == NULL || root->rc == pr) {            cout << root->data << ends;            pr = root;//将当前结点地址赋值rootre作为下一次判断标志,防止重复访问            s.pop();            root = NULL;//root赋值空以便访问右子树        } else {            root = root->rc;//访问子树的右子树        }    }}int main(){    NODE *root = NULL;    root = buildtree();     cout<<"前序:";     preorder(root);    cout<<endl<<"中序:";    inorder(root);    cout<<endl<<"后序: ";    postorder(root);}/*测试数据:DBA##C##EF##G##*/ 
原创粉丝点击