算法导论:第10章
10.4-5 O(n)非递归O(1)空间遍历二叉树树节点
转自http://blog.csdn.net/mishifangxiangdefeng/article/details/7708490
采用类似中序遍历的处理方法,对一个结点,可以分为以下几种情况
1.从父结点进入子结点进行处理
(1)如果有左孩子,就处理左孩子
(2)返回到自己
(3)访问自己
(4)如果有右孩子,就处理右孩子
(5)返回到自己的父结点
2.从左孩子返回,说明左孩子已经处理过,自己还没访问,自己的右孩子也没有处理过,就进行1-(2)
3.从右孩子返回,说明左右孩子都已经处理,自己也访问过,就返回到更上层
4.返回到根结点时,遍历结束
#include <iostream> using namespace std; //二叉树结点的结构体 struct node { int key;//值 node *left;//指向左孩子 node *right;//指向右孩子 node(){}//默认构造函数 node(int x):key(x),left(NULL),right(NULL){}//构造函数 }; //树的结构体 struct tree { node *root;//树中只有一个指向根结点的指针 tree():root(NULL){}//构造函数 }; /************10.4-2-递归地遍历访问二叉树***************************************/ //输出访问某个结点 void Node_Print(node *N) { //访问当前结点 cout<<N->key<<' '; //递归地访问其左孩子 if(N->left) Node_Print(N->left); //递归地访问其右孩子 if(N->right) Node_Print(N->right); } //遍历二叉树 void Tree_Print(tree *T) { //只孩子访问根结点,其它结点都在递归中访问了 Node_Print(T->root); cout<<endl; } /*************10.4-3-非递归地遍历二叉树*******************************************/ //把x结点压入栈S的顶部 void Push(node *S, node x) { S[0].key++; S[S[0].key] = x; } //弹出栈顶元素并返回 node* Pop(node *S) { if(S[0].key == 0) return NULL; node *ret = &S[S[0].key]; S[0].key--; return ret; } //用非递归的方式遍历二叉树 void Tree_Print2(tree *T) { //这种方式要借助一个栈来实现,栈的大小为树的深度 node Stack[15] = {0};//简单的数组栈,Stack[0]存储栈顶位置 node *t = T->root; //当处理一个结点时,做如下处理 while(1) { //访问这个结点 cout<<t->key<<' '; //入栈 Push(Stack, *t); //如果有左孩子,下一步处理其左孩子 if(t->left) t = t->left; //如果没有左孩子 else { do{ //弹出栈顶元素 t = Pop(Stack); //若栈中元素已经全部弹出,那么二叉树访问结束了 if(t == NULL) { cout<<endl; return; } } //如果这个栈顶元素没有右孩子,则继续出栈,直到访问结束或找到一个有右孩子的元素 while(t->right == NULL); //如果这个栈顶元素有右孩子,则访问其右孩子 t = t->right; } } } /*input:0=NIL 12 7 3 15 8 0 4 10 0 10 5 9 2 0 0 18 1 4 7 0 0 14 6 2 21 0 0 5 0 0 */ int main() { //构造一棵树按照10.4-1 int i; node A[11];//这个数组仅仅用于构造10.4-1中的树,在遍历时不使用 for(i = 1; i <= 10; i++) { int key, left, right; cin>>key>>left>>right; A[i].key = key; if(left) A[i].left = &A[left]; else A[i].left = NULL; if(right) A[i].right = &A[right]; else A[i].right = NULL; } //生成一棵树 tree *T = new tree(); T->root = &A[6]; //10.4-2,递归方式 Tree_Print(T); //10.4-3,非递归方式 Tree_Print2(T); return 0; }