![]()
1 二叉查找树
2 <?php
3
4 /**
5 * 节点类
6 */
7 class Node
8 {
9 public $val;
10 public $left;
11 public $right;
12
13 public function __construct( $val )
14 {
15 $this->val = $val;
16 }
17 }
18
19 /**
20 * 二叉搜索树;
21 */
22 class SearchTree
23 {
24 private $_root; //根节点
25
26 public function __construct()
27 {
28 $this->_root = null;
29 }
30
31 public function insert( $val )
32 {
33 $this->_root = $this->_insert( $val, $this->_root );
34 return $this->_root;
35 }
36
37 private function _insert( $val, $tree )
38 {
39 if( $tree == null ) {
40 $node = new Node( $val );
41 return $node;
42 }
43
44 if( $val > $tree->val ) {
45 $tree->right = $this->_insert( $val, $tree->right );
46 }else if( $val < $tree->val ) {
47 $tree->left = $this->_insert( $val, $tree->left );
48 }else {
49 // do nothing.
50 }
51 return $tree;
52 }
53
54 public function find( $x )
55 {
56 return $this->_find( $x, $this->_root );
57 }
58
59 private function _find( $x, $tree )
60 {
61 if( $tree == null )
62 return null;
63
64 if( $tree->val == $x )
65 return $tree;
66 else if( $tree->val > $x ) {
67 return $this->_find( $x, $tree->left );
68 }else {
69 return $this->_find( $x, $tree->right );
70 }
71 }
72
73 public function findMax()
74 {
75 $tmp = $this->_root;
76 while( $tmp && $tmp->right ) {
77 $tmp = $tmp->right;
78 }
79
80 return $tmp;
81 }
82
83 public function findMin( $tree = null )
84 {
85 $tmp = $tree ? $tree : $this->_root;
86 while( $tmp && $tmp->left ) {
87 $tmp = $tmp->left;
88 }
89
90 return $tmp;
91 }
92
93 public function delete( $x )
94 {
95 $this->_root = $this->_delete( $x, $this->_root );
96 return $this->_root;
97 }
98
99 public function _delete( $x, $tree )
100 {
101 if( $tree == null )
102 return $tree;
103
104 if( $x > $tree->val ) {
105 $tree->right = $this->_delete( $x, $tree->right );
106 }else if( $x < $tree->val ) {
107 $tree->left = $this->_delete( $x, $tree->left );
108 }else {
109 //删除节点。
110 if( $tree->left == null && $tree->right == null ) {
111 //叶子节点,直接删除
112 $tree = null;
113 return $tree;
114 }
115
116 if( $tree->left == null ) {
117 $tree = $tree->right;
118 }else if( $tree->right == null ) {
119 $tree = $tree->left;
120 }else {
121 //左右都有子节点。右边找最小子节点 代替当前节点
122 $rightMin = $this->findMin( $tree->right );
123 $tree->right = $this->_delete( $rightMin->val, $tree->right );
124 $rightMin->left = $tree->left;
125 $rightMin->right = $tree->right;
126 $tree = $rightMin;
127 unset( $rightMin );
128 }
129 }
130 return $tree;
131 }
132
133 /**
134 * 中序输出
135 */
136 public function inEcho()
137 {
138 $this->_inEcho( $this->_root );
139 echo '~~~~~~~~~~ ' . PHP_EOL;
140 }
141
142 private function _inEcho( $tree )
143 {
144 if( $tree == null ) {
145 return;
146 }
147
148 $this->_inEcho( $tree->left );
149 echo $tree->val . PHP_EOL;
150 $this->_inEcho( $tree->right );
151 }
152
153 public function dump()
154 {
155 $ret = [];
156 if( $this->_root == null )
157 return $ret;
158
159 $stack = new SplStack();
160 $stack->push( [$this->_root] );
161 while( !$stack->isEmpty() ) {
162 $node = $stack->pop();
163
164 $temp = $stackVal = [];
165 $isAllNull = true;
166 foreach( $node as $_node ) {
167 if( $_node == null )
168 $temp[] = '';
169 else {
170 $temp[] = $_node->val;
171 $isAllNull = false;
172 }
173
174 if( $_node && $_node->left ) {
175 $stackVal[] = $_node->left;
176 }else {
177 $stackVal[] = null;
178 }
179 if( $_node && $_node->right ) {
180 $stackVal[] = $_node->right;
181 }else {
182 $stackVal[] = null;
183 }
184 }
185 if( !$isAllNull ) {
186 if( $stackVal ) $stack->push( $stackVal );
187 if( $temp ) $ret[] = $temp;
188 }
189 }
190
191 $retCount = count( $ret ) - 1;
192 foreach( $ret as $_retVal ) {
193 echo str_repeat( ' ', $retCount );
194 $_retValCount = count( $_retVal );
195 $_tempEcho = '';
196 for( $i = 0; $i < $_retValCount; $i+= 2 ) {
197 $_tempEcho .= '|';
198 if( isset( $_retVal[$i+1] ) ){
199 $_tempEcho .= $_retVal[$i] . '-' . $_retVal[$i+1];
200 }else
201 $_tempEcho .= $_retVal[$i];
202 $_tempEcho .= '|';
203 }
204 echo str_replace( '||', '|', $_tempEcho );
205 $retCount--;
206 echo PHP_EOL;
207 }
208 }
209
210 }
211
212
213 $tree = new SearchTree();
214 $tree->insert( 100 );
215 $tree->insert( 20 );
216 $tree->insert( 30 );
217 $tree->insert( 15 );
218 $tree->insert( 5 );
219 $tree->insert( 90 );
220 $tree->insert( 17 );
221 $tree->insert( 18 );
222 $tree->insert( 188 );
223 $tree->dump();
224 // $tree->delete( 100 );
225 // $tree->dump();
226 // var_dump( $tree->find( 150 ) );
227 var_dump( $tree->findMax() );
View Code
![]()
1 avl树
2 <?php
3 class Node
4 {
5 public $val;
6 public $left;
7 public $right;
8 public $height;
9
10 public function __construct( $val )
11 {
12 $this->val = $val;
13 $this->height = 0;
14 }
15 }
16
17
18 class AvlTree
19 {
20 private $_root;
21
22 public function __construct()
23 {
24 $this->_root = null;
25 }
26
27 public function find( $x )
28 {
29 return $this->_find( $x, $this->_root );
30 }
31
32 private function _find( $x, $tree )
33 {
34 if( $tree == null )
35 return null;
36
37 if( $tree->val == $x )
38 return $tree;
39 else if( $tree->val > $x ) {
40 return $this->_find( $x, $tree->left );
41 }else {
42 return $this->_find( $x, $tree->right );
43 }
44 }
45
46 public function findMax()
47 {
48 $tmp = $this->_root;
49 while( $tmp && $tmp->right ) {
50 $tmp = $tmp->right;
51 }
52
53 return $tmp;
54 }
55
56 public function findMin( $tree = null )
57 {
58 $tmp = $tree ? $tree : $this->_root;
59 while( $tmp && $tmp->left ) {
60 $tmp = $tmp->left;
61 }
62
63 return $tmp;
64 }
65
66 public function getHeight( $tree ) {
67 if( $tree == null )
68 return -1;
69 else
70 return $tree->height;
71 }
72
73 public function insert( $x )
74 {
75 $this->_root = $this->_insert( $x, $this->_root );
76 return $this->_root;
77 }
78
79 private function _insert( $val, $tree )
80 {
81 if( $tree == null ) {
82 $node = new Node( $val );
83 return $node;
84 }
85
86 if( $val > $tree->val ) {
87 $tree->right = $this->_insert( $val, $tree->right );
88 if( $this->getHeight( $tree->right ) - $this->getHeight( $tree->left ) == 2 ) {
89 if( $val > $tree->right->val ) {
90 // var_dump( "val = {$val} ;; rotate = singleRotateWithRight ");
91 $tree = $this->singleRotateWithRight( $tree );
92 }else {
93 // var_dump( "val = {$val} ;; rotate = doubleRotateWithRight ");
94 $tree = $this->doubleRotateWithRight( $tree );
95 }
96 }
97 }else if( $val < $tree->val ) {
98 $tree->left = $this->_insert( $val, $tree->left );
99 if( $this->getHeight( $tree->left ) - $this->getHeight( $tree->right ) == 2 ) {
100 if( $val < $tree->left->val ) {
101 // var_dump( "val = {$val} ;; rotate = singleRotateWithLeft ");
102
103 $tree = $this->singleRotateWithLeft( $tree );
104 }else {
105 // var_dump( "val = {$val} ;; rotate = doubleRotateWithLeft ");
106
107 $tree = $this->doubleRotateWithLeft( $tree );
108 }
109 }
110 }else {
111 // do nothing.
112 }
113
114 $tree->height = max( $this->getHeight( $tree->left ), $this->getHeight( $tree->right ) ) + 1;
115
116 return $tree;
117 }
118
119 private function singleRotateWithRight( $tree )
120 {
121 $newRoot = $tree->right;
122 $tree->right = $newRoot->left;
123 $newRoot->left = $tree;
124
125 $newRoot->height = max( $this->getHeight( $newRoot->left ), $this->getHeight( $newRoot->right ) ) + 1;
126 $tree->height = max( $this->getHeight( $tree->left ), $this->getHeight( $tree->right ) ) + 1;
127
128 return $newRoot;
129 }
130
131 private function singleRotateWithLeft( $tree )
132 {
133 $newRoot = $tree->left;
134 $tree->left = $newRoot->right;
135 $newRoot->right = $tree;
136
137 $newRoot->height = max( $this->getHeight( $newRoot->left ), $this->getHeight( $newRoot->right ) ) + 1;
138 $tree->height = max( $this->getHeight( $tree->left ), $this->getHeight( $tree->right ) ) + 1;
139
140 return $newRoot;
141 }
142
143 private function doubleRotateWithRight( $tree )
144 {
145 $tree->right = $this->singleRotateWithLeft( $tree->right );
146 return $this->singleRotateWithRight( $tree );
147 }
148
149 private function doubleRotateWithLeft( $tree )
150 {
151 $tree->left = $this->singleRotateWithRight( $tree->left );
152 return $this->singleRotateWithLeft( $tree );
153 }
154
155 public function dump()
156 {
157 $ret = [];
158 if( $this->_root == null )
159 return $ret;
160
161 $stack = new SplStack();
162 $stack->push( [$this->_root] );
163 while( !$stack->isEmpty() ) {
164 $node = $stack->pop();
165
166 $temp = $stackVal = [];
167 $isAllNull = true;
168 foreach( $node as $_node ) {
169 if( $_node == null )
170 $temp[] = '';
171 else {
172 $temp[] = $_node->val;
173 $isAllNull = false;
174 }
175
176 if( $_node && $_node->left ) {
177 $stackVal[] = $_node->left;
178 }else {
179 $stackVal[] = null;
180 }
181 if( $_node && $_node->right ) {
182 $stackVal[] = $_node->right;
183 }else {
184 $stackVal[] = null;
185 }
186 }
187 if( !$isAllNull ) {
188 if( $stackVal ) $stack->push( $stackVal );
189 if( $temp ) $ret[] = $temp;
190 }
191 }
192
193 $retCount = count( $ret ) - 1;
194 foreach( $ret as $_retVal ) {
195 echo str_repeat( ' ', $retCount );
196 $_retValCount = count( $_retVal );
197 $_tempEcho = '';
198 for( $i = 0; $i < $_retValCount; $i+= 2 ) {
199 $_tempEcho .= '|';
200 if( isset( $_retVal[$i+1] ) ){
201 $_tempEcho .= $_retVal[$i] . '-' . $_retVal[$i+1];
202 }else
203 $_tempEcho .= $_retVal[$i];
204 $_tempEcho .= '|';
205 }
206 echo str_replace( '||', '|', $_tempEcho );
207 $retCount--;
208 echo PHP_EOL;
209 }
210 }
211
212 public function delete( $x )
213 {
214 $this->_root = $this->_delete( $x, $this->_root );
215 return $this->_root;
216 }
217
218 private function _delete( $val, $tree )
219 {
220 if( $tree == null )
221 return $tree;
222
223 if( $val > $tree->val ) {
224 $tree->right = $this->_delete( $val, $tree->right );
225 if( $this->getHeight( $tree->right ) - $this->getHeight( $tree->left ) == 2 ) {
226 if( $val > $tree->right->val ) {
227 $tree = $this->singleRotateWithRight( $tree );
228 }else {
229 $tree = $this->doubleRotateWithRight( $tree );
230 }
231 }
232 }else if( $val < $tree->val ) {
233 $tree->left = $this->_delete( $val, $tree->left );
234 if( $this->getHeight( $tree->left ) - $this->getHeight( $tree->right ) == 2 ) {
235 if( $val < $tree->left->val ) {
236 $tree = $this->singleRotateWithLeft( $tree );
237 }else {
238 $tree = $this->doubleRotateWithLeft( $tree );
239 }
240 }
241
242 }else {
243 if( $tree->left == null && $tree->right == null ) {
244 $tree = null;
245 return $tree;
246 }
247 if( $tree->left == null ) {
248 $tree = $tree->right;
249 }else if( $tree->right == null ) {
250 $tree = $tree->left;
251 }else {
252 $rightMin = $this->findMin( $tree->right );
253 $tree->right = $this->_delete( $rightMin->val, $tree->right );
254 $rightMin->left = $tree->left;
255 $rightMin->right = $tree->right;
256
257 $tree = $rightMin;
258 }
259 }
260
261 $tree->height = max( $this->getHeight( $tree->left ), $this->getHeight( $tree->right ) ) + 1;
262 return $tree;
263 }
264 }
265
266
267 $tree = new AvlTree();
268 $tree->insert(3);
269 $tree->insert(2);
270 $tree->insert(1);
271 $tree->insert(4);
272 $tree->insert(5);
273 $tree->insert(6);
274 $tree->insert(7);
275 $tree->insert(16);
276 $tree->insert(15);
277 $tree->insert(14);
278 $tree->insert(13);
279 $tree->insert(12);
280 $tree->insert(11);
281 $tree->insert(10);
282 $tree->insert(8);
283 $tree->insert(9);
284
285 $tree->delete(7);
286 $tree->delete(8);
287
288 $tree->dump();
289 // var_dump( $tree );
View Code
<?php
$arr = range(1, 100 );
shuffle( $arr );
function insertSort( $arr )
{
$count = count( $arr );
for( $i = 1; $i < $count; $i++ ) {
$max = $arr[$i];
for( $j = $i; $j > 0 && $arr[$j-1] > $max; $j-- ) {
$arr[$j] = $arr[$j-1];
}
$arr[$j] = $max;
}
return $arr;
}
print_R( insertSort( $arr ) );
function shellSort( $arr )
{
$count = count( $arr );
for( $step = $count >> 1; $step > 0; $step = $step >> 1 ) {
for( $i = $step; $i < $count; $i++ ) {
$max = $arr[$i];
for( $j = $i; $j - $step >= 0 && $arr[$j-$step] > $max; $j -= $step ) {
$arr[$j] = $arr[$j-$step];
}
$arr[$j] = $max;
}
}
return $arr;
}
print_r( shellSort( $arr ) );
function down( &$arr, $position, $count )
{
while( true ) {
$val = $arr[$position];
$left = ( $position * 2 ) + 1;
if( $left > $count - 1 )
break;
$right = $left + 1;
$maxkey = $left;
if( $right < $count && $arr[$right] > $arr[$left] )
$maxkey = $right;
if( $arr[$maxkey] > $val ) {
$arr[$position] = $arr[$maxkey];
$arr[$maxkey] = $val;
$position = $maxkey;
}else
break;
}
}
//create heap
function buildHeap( $arr )
{
$count = count( $arr );
for( $i = ( $count >> 1 ) - 1; $i >= 0; $i-- ) {
down( $arr, $i, $count );
}
return $arr;
}
print_r( buildHeap( [1,2,3,4,5,6] ) );
function percDown( &$arr, $i, $count )
{
$val = $arr[$i];
while( true ) {
$left = $i * 2 + 1;
if( $left > $count - 1 )
break;
$right = $left + 1;
$maxKey = $left;
if( $right <= $count - 1 && $arr[$right] > $arr[$left] )
$maxKey = $right;
if( $arr[$maxKey] > $val ) {
$arr[$i] = $arr[$maxKey];
$i = $maxKey;
}else
break;
}
$arr[$i] = $val;
}
function heapSort( $arr )
{
$count = count( $arr );
for( $i = $count >> 1; $i >=0; $i-- ) {
percDown( $arr, $i, $count );
}
for( $i = 0; $i < $count; $i++ ) {
list( $arr[$count-$i-1], $arr[0] ) = [$arr[0], $arr[$count-$i-1]];
percDown( $arr, 0, $count-$i-1 );
}
return $arr;
}
print_r( heapSort( $arr ) );
//归并
function mergeSort( $arr )
{
$count = count( $arr ) -1 ;
$temp = [];
return _mergeSort( $arr, 0, $count, $temp );
}
function _mergeSort( $arr, $start, $end, &$temp )
{
if( $start == $end ) {
return [$arr[$start]];
}
$mid = ( $end + $start ) >> 1;
$left = _mergeSort( $arr, $start, $mid, $temp );
$right = _mergeSort( $arr, $mid+1, $end, $temp );
$temp = [];
$lc = count( $left );
$rc = count( $right );
$lp = $rp = 0;
while( $lp < $lc && $rp < $rc ) {
if( $left[$lp] < $right[$rp] ) {
$temp[] = $left[$lp];
$lp++;
}else if( $left[$lp] > $right[$rp] ) {
$temp[] = $right[$rp];
$rp++;
}else {
$temp[] = $left[$lp];
$temp[] = $right[$rp];
$rp++;
$lp++;
}
}
while( $lp < $lc ) {
$temp[] = $left[$lp];
$lp++;
}
while( $rp < $rc ) {
$temp[] = $right[$rp];
$rp++;
}
return $temp;
}
// print_r( mergeSort( $arr ) );
function quickSort( $arr )
{
$count = count( $arr );
_quickSort( $arr, 0, $count -1 );
return $arr;
}
function _quickSort( &$arr, $start, $end )
{
if( $start >= $end ) {
return;
}
$i = $start + 1;
$j = $end;
$pivot = $arr[$start];
while( true ) {
while( $arr[$i] < $pivot && $i <= $j ) {
$i++;
}
while( $arr[$j] > $pivot && $j >= $i ) {
$j--;
}
if( $i < $j ) {
list( $arr[$i], $arr[$j] ) = [$arr[$j], $arr[$i]];
$i++;
$j--;
}else {
break;
}
}
list( $arr[$j], $arr[$start] ) = [$arr[$start], $arr[$j]];
_quickSort( $arr, $start, $j - 1 );
_quickSort( $arr, $j + 1, $end );
}
print_r( quickSort( [0,9,0,9,0,9,9,7,1] ) );