以防生疏,所以今天又写了一下二叉树的前中后序递归和非递归的实现:
二叉树的节点数据结构:
1 struct BinaryTreeNode 2 { 3 int nData; 4 5 BinaryTreeNode *lChild; 6 BinaryTreeNode *rChild; 7 };
最后用来测试的树:
1
/ \
2 4
\ / \
3 5 6
\
7
前序递归代码:
1 void RecursionBinaryTreePreOrder(BinaryTreeNode *root) 2 { 3 if (NULL == root) 4 { 5 return; 6 } 7 8 // 打印根节点 9 cout << root->nData << " "; 10 11 // 打印左孩子 12 RecursionBinaryTreePreOrder (root->lChild); 13 14 // 打印右孩子 15 RecursionBinaryTreePreOrder (root->rChild); 16 }
二叉树前序非递归遍历写了两种方式:
1 // 两种二叉树前序的非递归遍历方式 2 // 第一种 3 void BinaryTreePreOrder(BinaryTreeNode *root) 4 { 5 assert (root != NULL); 6 7 BinaryTreeNode *Stack[MAX]; 8 int nTop = -1; 9 10 // 根节点入栈 11 Stack[++nTop] = root; 12 13 while (nTop >= 0) 14 { 15 // 弹出并访问根节点 16 BinaryTreeNode *pTemp = Stack[nTop--]; 17 18 cout << pTemp->nData << " "; 19 20 // 因为根节点的左孩子要优于右孩子先访问, 21 // 根据栈FILO(先进后出)的特点,因此根节点的右孩子要先入栈 22 if (pTemp->rChild != NULL) 23 { 24 Stack[++nTop] = pTemp->rChild; 25 } 26 27 if (pTemp->lChild != NULL) 28 { 29 Stack[++nTop] = pTemp->lChild; 30 } 31 } 32 }
1 // 另一种非递归方式,这种方式是用栈来严格模拟递归的遍历方式 2 void AnotherBinaryTreePreOrder(BinaryTreeNode *root) 3 { 4 assert (root != NULL); 5 6 BinaryTreeNode *Stack[MAX]; 7 int nTop = -1; 8 BinaryTreeNode *pTemp = root; 9 10 while (pTemp != NULL) 11 { 12 cout << pTemp->nData << " "; 13 14 Stack[++nTop] = pTemp; 15 pTemp = pTemp->lChild; 16 } 17 18 while (nTop >= 0) 19 { 20 pTemp = Stack[nTop--]->rChild; 21 22 while (pTemp != NULL) 23 { 24 cout << pTemp->nData << " "; 25 26 Stack[++nTop] = pTemp; 27 pTemp = pTemp->lChild; 28 } 29 } 30 }
中序递归遍历:
1 // 二叉树中序的递归遍历方式 2 void RecursionBinaryTreeInOrder(BinaryTreeNode *root) 3 { 4 if (NULL == root) 5 { 6 return; 7 } 8 9 // 先打印左孩子 10 RecursionBinaryTreeInOrder (root->lChild); 11 12 // 再打印根节点 13 cout << root->nData << " "; 14 15 // 最后打印右孩子 16 RecursionBinaryTreeInOrder (root->rChild); 17 }
中序非递归遍历:
1 // 二叉树中序的非递归遍历方式,用栈严格模拟递归的调用 2 void BinaryTreeInOrder(BinaryTreeNode *root) 3 { 4 assert (root != NULL); 5 6 BinaryTreeNode *Stack[MAX]; 7 int nTop = -1; 8 9 // 根节点首先入栈 10 Stack[++nTop] = root; 11 12 // 先要打印左孩子 13 BinaryTreeNode *Current = root->lChild; 14 15 while ((Current != NULL) || (nTop >= 0)) 16 { 17 while (Current != NULL) 18 { 19 Stack[++nTop] = Current; 20 Current = Current->lChild; 21 } 22 23 // 打印根节点 24 Current = Stack[nTop--]; 25 cout << Current->nData << " "; 26 27 // 打印右孩子 28 Current = Current->rChild; 29 } 30 }
后序递归遍历:
1 // 二叉树后序的递归遍历方式 2 void RecursionBinaryTreePostOrder(BinaryTreeNode *root) 3 { 4 if (NULL == root) 5 { 6 return; 7 } 8 9 // 打印左孩子 10 RecursionBinaryTreePostOrder (root->lChild); 11 12 // 打印右孩子 13 RecursionBinaryTreePostOrder (root->rChild); 14 15 // 打印根节点 16 cout << root->nData << " "; 17 }
后序非递归遍历也写了两种方式:
1 // 二叉树后序的一种非递归遍历方式 2 void BinaryTreePostOrder(BinaryTreeNode *root) 3 { 4 assert (root != NULL); 5 6 BinaryTreeNode *Stack[MAX]; 7 int nTop = -1; 8 9 BinaryTreeNode *Current = root; 10 BinaryTreeNode *Previewed = NULL; 11 12 while ((Current != NULL) || (nTop >= 0)) 13 { 14 // 打印左孩子 15 while (Current != NULL) 16 { 17 Stack[++nTop] = Current; 18 Current = Current->lChild; 19 } 20 21 // 左孩子打印完,当其没有右孩子或右孩子已经被访问过,就打印根节点 22 // ,否则打印右孩子 23 Current = Stack[nTop]; 24 25 if ((NULL == Current->rChild) || (Previewed == Current->rChild)) 26 { 27 cout << Current->nData << " "; 28 Previewed = Current; 29 Current = NULL; 30 --nTop; 31 } 32 else 33 { 34 Current = Current->rChild; 35 } 36 } 37 }
1 // 二叉树后序的另一种非递归遍历方式 2 void AnotherBinaryTreePostOrder(BinaryTreeNode *root) 3 { 4 assert (root != NULL); 5 6 BinaryTreeNode *Stack1[MAX]; 7 int nTop1 = -1; 8 9 BinaryTreeNode *Stack2[MAX]; 10 int nTop2 = -1; 11 12 Stack1[++nTop1] = root; 13 14 while (nTop1 >= 0) 15 { 16 BinaryTreeNode *pTemp = Stack1[nTop1--]; 17 Stack2[++nTop2] = pTemp; 18 19 if (pTemp->lChild != NULL) 20 { 21 Stack1[++nTop1] = pTemp->lChild; 22 } 23 24 if (pTemp->rChild != NULL) 25 { 26 Stack1[++nTop1] = pTemp->rChild; 27 } 28 } 29 30 while (nTop2 >= 0) 31 { 32 cout << Stack2[nTop2--]->nData << " "; 33 } 34 }
测试结果: