非递归实现树的遍历

方法1:使用指针

View Code
  1 #include <iostream>
  2 using namespace std;
  3 
  4 struct node
  5 {
  6 int key;
  7 node *left;
  8 node *right;
  9 node *parent;
 10 node(){}
 11 node(int x):key(x),left(NULL),right(NULL){}
 12 };
 13 
 14 struct tree
 15 {
 16 node *root;
 17 tree():root(NULL){}
 18 };
 19 
 20 void Tree_Print(tree *T)
 21 {
 22 node *t = T->root;
 23 while(t)
 24 {
 25 if(t->left)
 26 {
 27 t = t->left;
 28 continue;
 29 }
 30 else
 31 {
 32 cout<<t->key<<' ';
 33 if(t->right)
 34 {
 35 t = t->right;
 36 continue;
 37 }
 38 while(1)
 39 {
 40 
 41 if(t == t->parent->left && t->parent->right)
 42 {
 43 cout<<t->parent->key<<' ';
 44 t = t->parent->right;
 45 break;
 46 }
 47 
 48 if(t == t->parent->left && t->parent->right == NULL)
 49 cout<<t->parent->key<<' ';
 50 t = t->parent;
 51 if(t == T->root)
 52 {
 53 cout<<endl;
 54 return;
 55 }
 56 }
 57 }
 58 }
 59 }
 60 /*input:0=NIL
 61 12 7 3
 62 15 8 0
 63 4 10 0
 64 10 5 9
 65 2 0 0
 66 18 1 4
 67 7 0 0
 68 14 6 2
 69 21 0 0
 70 5 0 0
 71 */
 72 int main()
 73 {
 74 //    构造一棵树按照10.4-1
 75 int i;
 76 node A[11];//这个数组仅仅用于构造10.4-1中的树,在遍历时不使用
 77 for(i = 1; i <= 10; i++)
 78 {
 79 int key, left, right;
 80 cin>>key>>left>>right;
 81 A[i].key = key;
 82 if(left)
 83 {
 84 A[i].left = &A[left];
 85 A[left].parent = &A[i];
 86 }
 87 else 
 88 A[i].left = NULL;
 89 if(right)
 90 {
 91 A[i].right = &A[right];
 92 A[right].parent = &A[i];
 93 }
 94 else A[i].right = NULL;
 95 }
 96 //生成一棵树
 97 tree *T = new tree();
 98 T->root = &A[6];
 99 10.4-5
100 Tree_Print(T);
101 system("pause");
102 return 0;
103 }

方法2:使用栈实现

View Code
  1 #include<iostream>
  2 #include <malloc.h>
  3 
  4 typedef struct _Bin_Tree
  5 {
  6 _Bin_Tree *pLeft;
  7 _Bin_Tree *pRight;
  8 int nData;
  9 }Bin_Tree;
 10 
 11 typedef struct _STACK
 12 {
 13 Bin_Tree *pData;
 14 _STACK *pNext;
 15 } STACK;
 16 
 17 //将一个节点置0
 18 void ZeroNode(Bin_Tree *pNode)
 19 {
 20 pNode->nData = 0;
 21 pNode->pLeft = 0;
 22 pNode->pRight = 0;
 23 }
 24 
 25 
 26 void CreateATree(Bin_Tree *pNode,int n)
 27 {
 28 Bin_Tree *pLeft=0,*pRight=0;
 29 if ( pNode == 0 ) return;
 30 
 31 pLeft = (_Bin_Tree *)malloc( sizeof(Bin_Tree) );
 32 ZeroNode( pLeft );
 33 pLeft->nData = n;
 34 pRight = (_Bin_Tree *)malloc( sizeof(Bin_Tree) );
 35 ZeroNode( pRight );
 36 pRight->nData = n+1;
 37 
 38 pNode->pLeft = pLeft;
 39 pNode->pRight = pRight;
 40 }
 41 
 42 //释放一个二叉树所占的内存
 43 void ReleaseTree(Bin_Tree **pNode)
 44 {
 45 if ( (*pNode) == 0 ) return;
 46 ReleaseTree( &((*pNode)->pLeft) );
 47 ReleaseTree( &((*pNode)->pRight) );
 48 free( (*pNode) );
 49 (*pNode) = 0;
 50 }
 51 
 52 //压栈
 53 void push( STACK * pS,STACK **pTop )
 54 {
 55 if( (*pTop) == 0 )
 56 {
 57 (*pTop) = pS;
 58 }
 59 else
 60 {
 61 pS->pNext = *pTop;
 62 (*pTop) = pS;//将栈指针上移
 63 }
 64 }
 65 
 66 //出栈
 67 STACK * pop( STACK **pTop )
 68 {
 69 if ( (*pTop) == 0 ) return 0;
 70 (*pTop) = (*pTop)->pNext;//栈顶指针下移
 71 return (*pTop);
 72 }
 73 
 74 //栈遍历前序
 75 //最要思想:
 76 //第一步将树的左分支的左节点压入栈,最后栈顶将是树最左边节点
 77 //然后从底部将栈中的每个节点放弹出,遍历其右节点,如果右节点还有分支,重复第一步.
 78 void PreOrder_stack( Bin_Tree *pRoot )
 79 {
 80 STACK *pSTop=0,*pSTemp=0;
 81 Bin_Tree *pTemp = pRoot;
 82 if ( pRoot == 0) return;
 83 
 84 while ( pTemp || pSTop != 0 )
 85 {
 86 if( pTemp )
 87 {
 88 STACK *pStack = (STACK *)malloc( sizeof( STACK ) );
 89 pStack->pData = pTemp;
 90 pStack->pNext = 0;
 91 printf("%d,",pTemp->nData);
 92 push( pStack, &pSTop );
 93 pTemp = pTemp->pLeft;
 94 }
 95 else
 96 {
 97 Bin_Tree *pSubRight = pSTop->pData->pRight;
 98 pSTemp = pSTop;
 99 pSTop = pop( &pSTop );
100 pTemp = pSubRight;
101 free(pSTemp);
102 pSTemp = 0;
103 }
104 }
105 }
106 
107 //栈遍历中序
108 //主要思想是将按左边寻址的方式,进行寻址,将每个节点压入栈。
109 //当左子到头后,再出弹栈,这样必然是先左、后中,再右。
110 void InOrder_stack( Bin_Tree *pRoot )
111 {
112 STACK *pSTop=0,*pSTemp=0;
113 Bin_Tree *pTemp = pRoot;
114 if ( pRoot == 0) return;
115 
116 while ( pTemp || pSTop != 0 )
117 {
118 if( pTemp )
119 {
120 STACK *pStack = (STACK *)malloc( sizeof( STACK ) );
121 pStack->pData = pTemp;
122 pStack->pNext = 0;
123 push( pStack, &pSTop );
124 pTemp = pTemp->pLeft;
125 }
126 else
127 {
128 pSTemp = pSTop;
129 pSTop = pop( &pSTop );
130 printf("%d,",pSTemp->pData->nData);
131 pTemp = pSTemp->pData->pRight;
132 free(pSTemp);
133 pSTemp = 0;
134 }
135 }
136 }
137 
138 //栈遍历后序
139 //主要思想是先遍历左右两个子树,再遍历根节点。
140 //后序遍历有一个需要主意的地方,就是从右树遍历完后,
141 //开始弹栈的时候,需要加一个pPre标记,该无数已经访问过,否则无法遍历完成。
142 void PostOrder_stack( Bin_Tree *pRoot )
143 {
144 STACK *pSTop=0,*pSTemp=0;
145 Bin_Tree *pTemp = pRoot, *pPre=0;
146 if ( pRoot == 0) return;
147 
148 while ( pTemp || pSTop != 0 )
149 {
150 while( pTemp )
151 {//遍历左子树
152 STACK *pStack = (STACK *)malloc( sizeof( STACK ) );
153 pStack->pData = pTemp;
154 pStack->pNext = 0;
155 push( pStack, &pSTop );
156 pTemp = pTemp->pLeft;
157 }
158 if ( pSTop->pData->pRight == 0 || pPre == pSTop->pData->pRight )
159 {//没有右子树或该节点刚被访问过
160 printf("%d,", pSTop->pData->nData);
161 pSTemp = pSTop;
162 pPre = pSTop->pData;
163 pSTop = pop( &pSTop );
164 pSTemp = 0;
165 }
166 else
167 {
168 pTemp = pSTop->pData->pRight;
169 }
170 }
171 }
172 
173  
原文地址:https://www.cnblogs.com/sanshuiyijing/p/3017852.html