球探比分网-足球即时比|球探比分足球即时比分手机版捷报|球探足球比分旧版本卡塔尔|188bet足球,计算器竞彩足球胜平负玩法,西超杯赛程比分排名,竞彩足球胜平负开奖结果公告

軟件開發(fā),網站建設,微信小程序制作,抖音小程序開發(fā)

態(tài)

業(yè)

軟件開發(fā),網站建設,微信小程序制作,抖音小程序開發(fā)
宜昌網站制作-PHP 實現(xiàn)二叉樹遍歷
發(fā)布時間:2024-12-09  閱讀量:344

二叉樹是樹的特殊一種,具有如下特點:

  1. 每個結點最多有兩顆子樹,結點的度最大為2。
  2. 左子樹和右子樹是有順序的,次序不能顛倒。
  3. 即使某結點只有一個子樹,也要區(qū)分左右子樹。

二叉樹的遍歷

深度優(yōu)先遍歷

對每一個可能的分支路徑深入到不能再深入為止,而且每個結點只能訪問一次。要特別注意的是,二叉樹的深度優(yōu)先遍歷比較特殊,可以細分為先序遍歷、中序遍歷、后序遍歷。具體說明如下:

前序遍歷:根節(jié)點->左子樹->右子樹

中序遍歷:左子樹->根節(jié)點->右子樹

后序遍歷:左子樹->右子樹->根節(jié)點

廣度優(yōu)先遍歷

又叫層次遍歷,從上往下對每一層依次訪問,在每一層中,從左往右(也可以從右往左)訪問結點,訪問完一層就進入下一層,直到沒有結點可以訪問為止。

實現(xiàn)

下面是PHP實現(xiàn)二叉樹的深度優(yōu)先遍歷。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?php

/**
* Class Node 節(jié)點
*/

class Node {
   public $value;
   public $left;
   public $right;

   public function __construct($value = null) {
       $this->value = $value;
   }
}

/**
* Class BinaryTree 二叉樹
*/

class BinaryTree {

   public $data;

   public function __construct($data = []) {
       $this->data = $data;
   }

   /**
    * 前序遍歷:
    *      根節(jié)點 -> 左子樹 -> 右子樹
    * 利用棧先進后出的特性,先訪問根節(jié)點,再把右子樹壓入,再壓入左子樹。
    * 這樣取出的時候是先取出左子樹,最后取出右子樹。
    *
    * @param $tree
    *
    * @return array
    */

   public function pre_order($tree) {
       $stack = [];
       $output = [];
       array_push($stack, $tree);
       while (!empty($stack)) {
           $center_node = array_pop($stack);
           // 先輸出根節(jié)點
           $output[] = $center_node->value;
           if ($center_node->right) {
               // 壓入右子樹
               array_push($stack, $center_node->right);
           }
           if ($center_node->left) {
               // 壓入左子樹
               array_push($stack, $center_node->left);
           }
       }
       return $output;
   }

   /**
    * 前序遍歷(遞歸)
    *
    * @param $tree
    * @param $output
    *
    * @return array|void
    */

   public function pre_order_recursive($tree, &$output) {
       if (is_null($tree)) return; else {
           $output[] = $tree->value;
           $this->pre_order_recursive($tree->left, $output);
           $this->pre_order_recursive($tree->right, $output);
       }
       return $output;
   }

   /**
    * 中序遍歷
    *      左子樹 -> 根節(jié)點 -> 右子樹
    * 需要從下向上遍歷,先把左子樹壓入棧,然后逐個訪問根節(jié)點和右子樹。
    *
    * @param $tree
    *
    * @return array
    */

   public function in_order($tree) {
       $stack = [];
       $output = [];
       $center_node = $tree;
       while (!empty($stack) || $center_node != null) {
           while ($center_node) {
               array_push($stack, $center_node);
               $center_node = $center_node->left;
           }

           $center_node = array_pop($stack);
           if ($center_node->value) {
               $output[] = $center_node->value;
           }
           $center_node = $center_node->right;
       }
       return $output;
   }

   /**
    * 中序遍歷(遞歸)
    *
    * @param $tree
    * @param $output
    *
    * @return array|void
    */

   public function in_order_recursive($tree, &$output) {
       if (is_null($tree)) return; else {
           $this->in_order_recursive($tree->left, $output);
           $output[] = $tree->value;
           $this->in_order_recursive($tree->right, $output);
       }
       return $output;
   }

   /**
    * 后序遍歷
    *      左子樹 -> 右子樹 -> 根節(jié)點
    * 先把根節(jié)點存起來,然后依次儲存左子樹和右子樹。然后輸出。
    *
    * @param $tree
    *
    * @return array
    */

   public function tail_order($tree) {
       $stack = [];
       $output = [];
       array_push($stack, $tree);
       while (!empty($stack)) {
           $center_node = array_pop($stack);
           $output[] = $center_node->value;
           if ($center_node->left) {
               array_push($stack, $center_node->left);
           }
           if ($center_node->right) {
               array_push($stack, $center_node->right);
           }
       }
       return array_reverse($output);
   }

   /**
    * 后序遍歷(遞歸)
    *
    * @param $tree
    * @param $output
    *
    * @return array|void
    */

   public function tail_order_recursive($tree, &$output) {
       if (is_null($tree)) return; else {
           $this->tail_order_recursive($tree->left, $output);
           $this->tail_order_recursive($tree->right, $output);
           $output[] = $tree->value;
       }
       return $output;
   }

   /**
    * 前序生成二叉樹
    *
    * @param $root
    *
    * @return Node|string|void
    */

   public function pre_order_create(&$root) {
       $data = array_shift($this->data);
       if (is_null($data)) return; elseif ($data == '#') return $root = null;
       else {
           $root = new Node($data);
           $this->pre_order_create($root->left);
           $this->pre_order_create($root->right);
       }
       return $root;
   }
}

// 構造二叉樹數據
$data = array(0 => 'A',
             1 => 'B',
             2 => '#',
             3 => 'D',
             4 => '#',
             5 => '#',
             6 => 'C',
             7 => '#',
             8 => '#',);

$bt = new BinaryTree($data);
// 前序生成
$tree = $bt->pre_order_create($root);

// 前序遍歷
// $output = $bt->pre_order($tree);
// $output = $bt->pre_order_recursive($tree, $output);

// 中序遍歷
// $output = $bt->in_order($tree);
// $output = $bt->in_order_recursive($tree, $output);

// 后序遍歷
// $output = $bt->tail_order($tree);
// $output = $bt->tail_order_recursive($tree, $output);

print_r($tree);