ldjhust

工欲善其事 必先利其器

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

以防生疏,所以今天又写了一下二叉树的前中后序递归和非递归的实现:

二叉树的节点数据结构:

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 }

测试结果:

posted on 2013-05-02 11:31  ldjhust  阅读(197)  评论(0编辑  收藏  举报