树的非递归遍历

来源:互联网 发布:淘宝店铺星级靠谱么 编辑:程序博客网 时间:2024/05/18 01:54

非递归遍历树算法以前我一直死记书本的用栈保存,最近笔试时要求写非递归遍历,想了很久都没有写好。回家后,我回顾重新学习了这个非递归遍历算法,总结了一下于是写下来记下。

其实遍历每个节点的过程中,有三种状态是必须记录下的,1、没访问左子树。2、已访问左子树。3、没访问右子树。每种状态须要执行的操作分别是,1、左孩子节点入栈,2、访问结点信息(中序遍历),3、右孩子节点入栈。其中已访问左子树,由下图的虚线表示,并且此时进行访问节点信息和弹栈操作。

非递归遍历算法,状态2的表示是关键,这个可以通过检测其是不是NULL节点返回来判断。

#include<cstdlib>#include<cstdio>#include<cstring>#include<iostream>#include<stack>#include<algorithm>using namespace std;struct Node{int value;Node *L, *R;};#define MemNode(nd) nd=(Node*)malloc(sizeof(*nd))void CreateTree(Node *&root){MemNode(root);root->value = 1;MemNode(root->L);MemNode(root->R);Node *L = root->L;Node *R = root->R;R->value = 4;R->L = R->R = NULL;L->value = 2;L->L = NULL;MemNode(L->R);L->R->value = 3;L->R->L = L->R->R = NULL;}int dfs(Node *p){if (p->L == NULL && p->R == NULL) {printf("%d\n",p->value);return p->value;}int lv = 0, rv = 0;if (p->L) lv = dfs(p->L);printf("%d\n", p->value);if (p->R) rv = dfs(p->R);return lv + rv + p->value;}void visit(Node *p,int &sum){sum += p->value;printf("%d\n",p->value);}int traverse(Node *p){stack<Node*> stTree;stTree.push(p);int sum = 0;while (!stTree.empty()){Node *nd = stTree.top(); if (nd != NULL){stTree.push(nd->L);}else{stTree.pop();if (!stTree.empty()){Node *tp = stTree.top(); stTree.pop();visit(tp, sum);stTree.push(tp->R);}}}return sum;}int main(){Node *root = NULL;CreateTree(root);int dfsTot = dfs(root);printf("sum = %d\n",dfsTot);printf("=================================================================");puts("\nNon-recursive Traverse");int traTot = traverse(root);printf("sum = %d\n",traTot);return 0;}
上面代码CreateTree是创建如图所示结构的树,dfs使用递归遍历树并求和,traverse使用了非递归算法。

0 0