-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathheap.php
215 lines (191 loc) · 5.51 KB
/
heap.php
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
209
210
211
212
213
214
215
<?php
/**
* Created by PhpStorm.
* User: lhs
* Date: 2019-06-18
* Time: 10:38
*/
/**
* Class heap
* 二叉堆【优先级队列】
* 二叉堆的定义是:父节点的键值总是不大于它的孩子节点的键值(小顶堆), 堆可以分为小顶堆和大顶堆。
* 在数组中i处的左子节点为 2 * i + 1 右子节点在 2 * i + 2,子节点的父节点在 (i-1)/2处
*/
class heap
{
public $heapArr = [];
protected $heapSize = -1;
/**
* @param $testArr
*
*/
public function init($testArr)
{
}
/**
* @param $val
*/
public function insert($val)
{
$this->heapSize++;
$this->heapArr[$this->heapSize] = $val;
$i = (count($this->heapArr) - 1);
while ($i >= 0) {
$j = ($i - 1) / 2;
if ($j >= 0 && $this->heapArr[$i] < $this->heapArr[$j]) {
$tmp = $this->heapArr[$i];
$this->heapArr[$i] = $this->heapArr[$j];
$this->heapArr[$j] = $tmp;
$i = $j;
} else {
break;
}
}
}
/**
*
*/
public function delete()
{
$i = $this->heapSize;
$minVal = $this->heapArr[0];
$lastVal = $this->heapArr[$i];
$j = 0;
while (2 * $j < $i) {
$left = 2 * $j + 1;
$right = 2 * $j + 2;
$t = $left;
if ($this->heapArr[$left] && $this->heapArr[$right] && $this->heapArr[$right] < $this->heapArr[$left]) {
$t = $right;
}
if ($lastVal > $this->heapArr[$j]) {
$this->heapArr[$j] = $this->heapArr[$t];
$j = $t;
} else {
break;
}
}
$this->heapArr[$j] = $lastVal;
unset($this->heapArr[$i]);
$this->heapSize--;
return $minVal;
}
/**
* @param array $arr
* @return array
*/
public function sort(array $arr)
{
//构建二叉堆
$length = count($arr);
for ($i = ($length - 2) / 2; $i >= 0; $i--) {
$arr = $this->down($arr, $i, $length);
}
var_dump($arr);
//进行堆排序
for ($i = $length - 1; $i >= 1; $i--) {
//把堆顶的元素与最后一个元素交换
$temp = $arr[$i];
$arr[$i] = $arr[0];
$arr[0] = $temp;
//下沉调整
$arr = $this->down($arr, 0, $i);
}
return $arr;
}
/**
* @param array $arr
* @param int $parent
* @param int $length
* @return array
*/
public function down(array $arr, int $parent, int $length)
{
//临时保证要下沉的元素
$temp = $arr[$parent];
//定位左孩子节点位置
$child = 2 * $parent + 1;
//开始下沉
while ($child < $length) {
//如果右孩子节点比左孩子小,则定位到右孩子
if ($child + 1 < $length && $arr[$child] > $arr[$child + 1]) {
$child++;
}
//如果父节点比孩子节点小或等于,则下沉结束
if ($temp <= $arr[$child]) {
break;
}
//单向赋值
$arr[$parent] = $arr[$child];
$parent = $child;
$child = 2 * $parent + 1;
}
$arr[$parent] = $temp;
return $arr;
}
function myHash($str) {
// hash(i) = hash(i-1) * 33 + str[i]
$hash = 5381;
$s = md5($str); //相比其它版本,进行了md5加密
$seed = 5;
$len = 32;//加密后长度32
for ($i = 0; $i < $len; $i++) {
// (hash << 5) + hash 相当于 hash * 33
//$hash = sprintf("%u", $hash * 33) + ord($s{$i});
//$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
$hash = ($hash << $seed) + $hash + ord($s{$i});
}
return $hash & 0x7FFFFFFF;
}
/**
* @param $data
* @param $pId
* @return array
*/
public function getTree($data, $pId)
{
$tree = array();
foreach($data as $k => $v)
{
if($v['parentid'] == $pId)
{ //父亲找到儿子
$v['parentid'] = $this->getTree($data, $v['id']);
$tree[] = $v;
}
}
return $tree;
}
}
$array = array(
1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'),
2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'),
3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'),
4 => array('id'=>'4','parentid'=>0,'name'=>'一级栏目一'),
5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目二'),
6 => array('id'=>'6','parentid'=>5,'name'=>'三级栏目一'),
7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目一'),
8 => array('id'=>'8','parentid'=>7,'name'=>'四级栏目二'),
9 => array('id'=>'9','parentid'=>1,'name'=>'二级栏目一'),
10 => array('id'=>'10','parentid'=>7,'name'=>'一级栏目一'),
11 => array('id'=>'11','parentid'=>2,'name'=>'二级栏目二')
);
$testArr = [
31,
21,
19,
68,
26,
65,
19,
14,
13,
16,
32
];
$heap = new heap();
/*foreach ($testArr as $val) {
$heap->insert($val);
}*/
//var_dump($heap->heapArr);
echo json_encode($heap->getTree($array,0));
//var_dump($heap->heapArr);