二叉树的非递归遍历
来源:互联网 发布:天天赚钱软件下载 编辑:程序博客网 时间:2024/06/06 00:16
1.前序遍历
对于任一结点P:
1)访问结点P,并将结点P入栈; 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1); 若不为空,则将P的左孩子置为当前的结点P; 3)直到P为NULL并且栈为空,则遍历结束。
//非递归先序遍历void preOrder2(node *root){ stack<node*> stk; node* p = root; while (p != NULL || !stk.empty()){ while (p != NULL){ cout << p->val << " "; stk.push(p); p = p->left; } if (!stk.empty()){ p = stk.top(); stk.pop(); p = p->right; } }}
3.中序遍历
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束
//非递归中序遍历void inOrder2(node* root){ stack<node*> stk; node* p = root; while (p != NULL || !stk.empty()){ while (p != NULL){ stk.push(p); p=p->left; } if (!stk.empty()){ p = stk.top(); stk.pop(); cout << p->val<<" "; p = p->right; } }}
3。后序遍历
后序遍历的非递归实现是三种遍历方式中最难的一种。因为在后序遍历中,要保证左孩子和右孩子都已被访问并且左孩子在右孩子前访问才能访问根结点。
对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。
所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。这样就保证了正确的访问顺序。
可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
void postOrder2(node* root){ stack<tmpNode*> stk; node* p = root; while (p != NULL || !stk.empty()){ while (p != NULL){ tmpNode *tpn = new tmpNode(p); stk.push(tpn); p = p->left; } if (!stk.empty()){ tmpNode* top = stk.top(); stk.pop(); if (top->isFirst){ top->isFirst = false; //重新压到栈中 stk.push(top); p = top->u->right; } else{ cout << top->u->val << " " ; p=NULL; } } }}
.
完整代码
#include<iostream>#include<string>#include<sstream>#include<stack>using namespace std;struct node{ int val; node* left; node* right; node(int val) :val(val), left(NULL), right(NULL){}};struct tmpNode{ node* u; bool isFirst; tmpNode(node* u) :u(u), isFirst(true){}};node* builtTreeHelper(istringstream& is){ string str; is >> str; if (str == "#"){ return NULL; } node *u = new node(atoi(str.c_str())); u->left = builtTreeHelper(is); u->right = builtTreeHelper(is); return u;}node* builtTree(string str){ istringstream is(str); node* root = builtTreeHelper(is); return root;}void preOrder(node *root){ if (root){ cout << root->val << " "; } if (root->left) preOrder(root->left); if (root->right) preOrder(root->right);}//非递归先序遍历void preOrder2(node *root){ stack<node*> stk; node* p = root; while (p != NULL || !stk.empty()){ while (p != NULL){ cout << p->val << " "; stk.push(p); p = p->left; } if (!stk.empty()){ p = stk.top(); stk.pop(); p = p->right; } }}//非递归中序遍历void inOrder2(node* root){ stack<node*> stk; node* p = root; while (p != NULL || !stk.empty()){ while (p != NULL){ stk.push(p); p=p->left; } if (!stk.empty()){ p = stk.top(); stk.pop(); cout << p->val<<" "; p = p->right; } }}void postOrder2(node* root){ stack<tmpNode*> stk; node* p = root; while (p != NULL || !stk.empty()){ while (p != NULL){ tmpNode *tpn = new tmpNode(p); stk.push(tpn); p = p->left; } if (!stk.empty()){ tmpNode* top = stk.top(); stk.pop(); if (top->isFirst){ top->isFirst = false; //重新压到栈中 stk.push(top); p = top->u->right; } else{ cout << top->u->val << " " ; } } }}int main(){ string str = "5 7 # 6 # # 3 # #"; node* root = builtTree(str); cout << "先序遍历" << endl; preOrder2(root); cout << endl << "中序遍历" << endl; inOrder2(root); cout << endl<< "后序遍历" << endl; postOrder2(root); cout << endl; return 0;}
参考
http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
1 0
- 二叉树的递归,非递归遍历
- 二叉树的递归+非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的遍历--递归+非递归
- 二叉树的递归、非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的先中后序遍历,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的创建,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的非递归遍历以及递归遍历
- 二叉树的非递归遍历&递归遍历
- 二叉树的递归遍历和非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历和非递归遍历
- 二叉树的构造,递归遍历,非递归遍历
- 二叉树的遍历(递归+非递归+层次遍历)
- 二叉树的递归遍历与非递归遍历
- iOS MVVM+RAC 从框架到实战
- eclipse中修改字体大小
- javaBean
- UVA 10048 Audiophobia(Floyd变形)
- java单链表基本操作(二)--指定位置增加节点
- 二叉树的非递归遍历
- 文章标题warning: could not load any Objective-C class information. This will significantly reduce the qu
- LeetCode *** 104. Maximum Depth of Binary Tree
- android面试题50道
- 扇形比例表(猜涨跌)
- Android内存优化之OOM
- 数组型Json解析之细节
- iOS 开发之照片框架详解
- 5 个免费的受欢迎的 SQLite 管理工具