树的遍历

2.3二叉树的遍历

树的表示

1 //树的表示
2 typedef struct TreeNode *BinTree;
3 struct  TreeNode
4 {
5     int Data;//存值
6     BinTree Left;//左儿子结点
7     BinTree Right;//右儿子结点
8 };

2.3.1先序

  • 先访问根结点
  • 先序遍历其左子树
  • 先序遍历其右子树

 

1 //先序遍历 递归实现
2 void PreOrderTraversal(BinTree BT) {
3     if (BT) {
4         printf("%d", BT->Data);//首次遇到即访问
5         PreOrderTraversal(BT->Left);
6         PreOrderTraversal(BT->Right);
7     }
8 }
 1 //先序遍历 非递归实现
 2 void PreOrderTraversal(BinTree BT) {
 3     BinTree T = BT;
 4     Stack S = CreatStack();//创建并初始化堆栈
 5     while(T||!IsEmpty(S)){
 6         while (T) {//当树不为空的时候
 7             printf("%d", T->Data);//第一次遇见就访问输出
 8             Push(S, T);
 9             T = T->Left;//遍历左子树
10         }
11         if (!IsEmpty(S)) {
12             T = Pop(S);//已经访问过了直接弹出
13             T = T->Right;
14         }
15     }
16 }

2.3.2中序

  • 中序遍历其左子树
  • 访问根结点
  • 中序遍历其右子树

遍历结果:(DBEF)A(GHCI)

1 //中序遍历 递归实现
2 void InOrderTraversal(BinTree BT) {
3     if (BT) {
4         InOrderTraversal(BT->Left);
5         printf("%d", BT->Data);
6         InOrderTraversal(BT->Right);
7     }
8 }
 1 //中序遍历 非递归  与中序遍历作比较只有printf("%d", T->Data)的位置不同
 2 void InOrderTraversal(BinTree BT) {
 3     BinTree T = BT;
 4     Stack S = CreatStack();
 5     while (T || !IsEmpty(S)) {
 6         while (T)
 7         {
 8             Push(S, T);//第一次遇到的时候不访问,将其压入堆栈
 9             T = T->Left;
10         }
11         if (!IsEmpty(S)) {
12             T = Pop(S);
13             printf("%d", T->Data);//第二次遇到的时候访问
14             T = T->Right;
15         }
16     }
17 }

2.3.3后序

  • 后序遍历其左子树
  • 后序遍历其右子树
  • 访问根结点

遍历结果:(DEFB)(HGIC)A

1 //后序遍历 递归实现
2 void PostOrderTraversal(BinTree BT) {
3     PostOrderTraversal(BT->Left);
4     PostOrderTraversal(BT->Right);
5     printf("%d", BT->Data);
6 }
 1 //后序遍历非递归实现
 2 void PostOrderTraversal(BinTree BT) {
 3     BinTree T = BT;
 4     Stack S = CreatStack();
 5     vector<BinTree>v; 
 6     Push(S, T);
 7     while (!IsEmpty(S)){
 8         T = Pop(S);
 9         v.push_back(T);
10         if (T->Left)
11             Push(S, T->Left);
12         if (T->Right)
13             Push(S, T->Right);
14     }
15     reverse(v.begin(), v.end());//进行翻转 因为出栈入动态数组的时候是先右后左
16     for (int i = 0; i < v.size(); i++)
17         printf("%d", v[i]->Data);
18     return 0;
19 }

 

归纳:

  • 以上三种遍历过程中经过结点的路线一样,只是访问各结点的时机不同。
  • 由两种遍历结果可知树的结构,前提是两种之一必须是中序遍历。
  • 二叉树遍历的核心问题:二维结构的线性化

 

2.3.4层序遍历

用队列实现层序遍历:将根结点入队,将根结点出队,然后将根结点的左右儿子入队。

遍历结果:ABCDFGIFH

 1 //层序遍历 使用队列
 2 void LevelOrderTraversal(BinTree BT) {
 3     Queue Q = CreatQueue();
 4     BinTree T;
 5     if (!BT) {
 6         return;//如果树空则返回
 7     }
 8     AddQ(Q, BT);
 9     while (!IsEmpty(Q))
10     {
11         T = DeleteQ(Q);
12         printf("%d", T->Data);
13         if (T->Left)AddQ(Q, T->Left);
14         if (T->Right)AddQ(Q, T->Right);
15     }
16 }

 

posted @ 2020-03-28 12:51  PennyXia  阅读(171)  评论(0编辑  收藏  举报