程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 二叉樹的遍歷,二叉樹遍歷

二叉樹的遍歷,二叉樹遍歷

編輯:關於C語言

二叉樹的遍歷,二叉樹遍歷


  二叉樹的遍歷一般分為三種遍歷方法,即先序遍歷、中序遍歷和後序遍歷。

  在中序遍歷中,一個節點的前驅,是其左子樹的最右下角結點,後繼,是其右子樹的最左下角結點。
  在後序遍歷中,
  •  若結點是根結點,則其後繼為空;
  •   若結點是雙親的右子樹,或是左子樹但雙親無右子樹,則其後繼為雙親結點;
  •   若結點是雙親的左子樹且雙親有右子樹,則其後繼為右子樹按後序遍歷的第一個結點

 

二叉樹的遍歷實現如下:

  1 #include <stack>
  2 #include <queue>
  3 
  4 /*
  5 *@struct
  6 *@brief 二叉樹結點
  7 */
  8 typedef struct binary_tree_node_t 
  9 {
 10   binary_tree_node_t *lchild;  /* 左孩子 */
 11   binary_tree_node_t *rchild;  /* 右孩子 */
 12   void* data; /* 結點的數據 */
 13 }binary_tree_node_t;
 14 
 15 /**
 16 * @brief 先序遍歷,遞歸.
 17 * @param[in] root 根結點
 18 * @param[in] visit 訪問數據元素的函數指針
 19 * @return 無
 20 */
 21 void pre_order_r(const binary_tree_node_t *root, int (*visit)(void*)) 
 22 {
 23   if(root != NULL)
 24   {
 25     (void)visit(root->data);
 26     pre_order_r(root->lchild, visit);
 27     pre_order_r(root->rchild, visit);
 28   }
 29 }
 30 
 31 /**
 32 * @brief 中序遍歷,遞歸.
 33 */
 34 void in_order_r(const binary_tree_node_t *root, int (*visit)(void*)) 
 35 {
 36   if(root != NULL) 
 37   {
 38     pre_order_r(root->lchild, visit);
 39     (void)visit(root->data);
 40     pre_order_r(root->rchild, visit);
 41   }
 42 }
 43 
 44 /**
 45 * @brief 後序遍歷,遞歸.
 46 */
 47 void post_order_r(const binary_tree_node_t *root, int (*visit)(void*)) 
 48 {
 49   if(root != NULL) 
 50   {
 51     pre_order_r(root->lchild, visit);
 52     pre_order_r(root->rchild, visit);
 53     (void)visit(root->data);
 54   }
 55 }
 56 
 57 /**
 58 * @brief 先序遍歷,非遞歸.
 59 */
 60 void pre_order(const binary_tree_node_t *root, int (*visit)(void*)) 
 61 {
 62   const binary_tree_node_t *p;
 63   std::stack<const binary_tree_node_t *> s;
 64   p = root;
 65   if(p != NULL) 
 66   {
 67     s.push(p);
 68   }
 69 
 70   while(!s.empty()) 
 71   {
 72     p = s.top();
 73     s.pop();
 74     visit(p->data);
 75     if(p->rchild != NULL) 
 76     {
 77       s.push(p->rchild);
 78     }
 79     if(p->lchild != NULL) 
 80     {
 81       s.push(p->lchild);
 82     }
 83   }
 84 }
 85 
 86 /**
 87 * @brief 中序遍歷,非遞歸.
 88 */
 89 void in_order(const binary_tree_node_t *root, int (*visit)(void*)) 
 90 {
 91   const binary_tree_node_t *p;
 92   std::stack<const binary_tree_node_t *> s;
 93   p = root;
 94   while(!s.empty() || p!=NULL) 
 95   {
 96     if(p != NULL) 
 97     {
 98       s.push(p);
 99       p = p->lchild;
100     } 
101     else 
102     {
103       p = s.top();
104       s.pop();
105       visit(p->data);
106       p = p->rchild;
107     }
108   }
109 }
110 
111 /**
112 * @brief 後序遍歷,非遞歸.
113 */
114 void post_order(const binary_tree_node_t *root, int (*visit)(void*)) 
115 {
116   /* p,正在訪問的結點,q,剛剛訪問過的結點 */
117   const binary_tree_node_t *p, *q;
118   std::stack<const binary_tree_node_t *> s;
119   p = root;
120   do {
121     while(p != NULL) 
122     { 
123       /* 往左下走 */
124       s.push(p);
125       p = p->lchild;
126     }
127     q = NULL;
128     while(!s.empty()) 
129     {
130       p = s.top();
131       s.pop();
132       /* 右孩子不存在或已被訪問,訪問之 */
133       if(p->rchild == q) 
134       {
135         visit(p->data);
136         q = p; /* 保存剛訪問過的結點 */
137       } 
138       else 
139       {
140         /* 當前結點不能訪問,需第二次進棧 */
141         s.push(p);
142         /* 先處理右子樹 */
143         p = p->rchild;
144         break;
145       }
146     }
147   }while(!s.empty());
148 }
149 
150 /**
151 * @brief 層次遍歷,也即 BFS.
152 *
153 * 跟先序遍歷一模一樣,唯一的不同是棧換成了隊列
154 */
155 void level_order(const binary_tree_node_t *root, int (*visit)(void*)) 
156 {
157   const binary_tree_node_t *p;
158   std::queue<const binary_tree_node_t *> q;
159   p = root;
160   if(p != NULL) 
161   {
162     q.push(p);
163   }
164   while(!q.empty()) 
165   {
166     p = q.front();
167     q.pop();
168     visit(p->data);
169     if(p->lchild != NULL) 
170     {
171       /* 先左後右或先右後左無所謂 */
172       q.push(p->lchild);
173     }
174     if(p->rchild != NULL) 
175     {
176       q.push(p->rchild);
177     }
178   }
179 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved