树的非递归便利,中序和后序

来源:互联网 发布:快速出效果图软件 编辑:程序博客网 时间:2024/06/03 11:38

把递归转成非递归的基本思想是用栈保留临时状态。对于先序遍历很简单,对于中序和后序遍历要稍微麻烦点。

分析中序的过程:对于当前节点,如果有左子树,说明不是当前应该访问的节点,应该入栈然后考察其左子树,否则就在出栈的过程中访问该节点。如果访问了当前节点后,其有右子树,则应该访问其右子树后,再访问其父节点,因此要优先考察右节点。

分析后序的过程:对于当前节点,如果有左子树,同中序。如果出栈后没有右子树,则访问。如果有右子树,则不能出栈,并且访问右子树,等到再次在出栈的过程中发现这个节点就访问。

#include<iostream>#include<malloc.h>#include<stack>#include<set>using namespace std;typedef struct treenode{int data;treenode *left;treenode *right;}treenode;bool error = false;treenode* precreate(){int data;cin>>data;if(data == 0 || error)return NULL;treenode *node = (treenode*)malloc(sizeof(treenode));if(node == NULL){error = true;return NULL;}node->data = data;node->left = precreate();node->right = precreate();return node;}void midsearch(treenode *root){treenode *p = root;stack<treenode*> stac;while(p!=NULL){stac.push(p);p = p->left;}while(!stac.empty()){p = stac.top();stac.pop();cout<<p->data<<endl;if(p->right != NULL){p = p->right;while(p!=NULL){stac.push(p);p = p->left;}}}}void postsearch(treenode *root){set<treenode*> once;stack<treenode*> stac;treenode* p = root;while(p != NULL){stac.push(p);p = p->left;}while(!stac.empty()){p = stac.top();stac.pop();if(p->right == NULL)cout<<p->data<<endl;else{if(once.find(p)!=once.end()){cout<<p->data<<endl;}else{stac.push(p);once.insert(p);p = p->right;while(p != NULL){stac.push(p);p = p->left;}}}}}void treefeidigui_foo(){treenode *root = precreate();//midsearch(root);postsearch(root);}