1 # basic node format of Heap
2
3 class HeapNode {
4
5 var $value;
6
7 }
8
9 # the format of this Heap's node should like the
10 # class HeapNode:contain $value to compare
11
12 class Heap {
13
14 var $flag; // true:queue from small to big; false:from big to small
15 var $array; // the array for saving nodes
16
17 #constructor of this class
18
19 function Heap($param = true) {
20 global $flag;
21 $flag = $param;
22 }
23
24 #push node into array, no length limit
25
26 function push($node) {
27 global $array;
28 if (empty($array)) {
29 $array = array($node);
30 } else {
31 array_push($array, $node);
32 }
33 $idx = count($array) - 1;
34 // push in the last position, than adjust from bottom to top
35 while ($this->cmp($array[$idx], $array[($idx - 1) / 2])) {
36 $this->swap($array[$idx], $array[($idx - 1) / 2]);
37 $idx = ($idx - 1) / 2;
38 }
39 }
40
41 #pop the min/max node, return success:true/fail:false
42
43 function pop() {
44 global $array;
45
46 if (empty($array)) { // pop empty heap, return fail
47 return false;
48 }
49 changeLastToRoot();
50 if (empty($array)) { // no element, finish this function
51 return true;
52 }
53 adjustRootNode();
54 return true;
55 }
56
57 # pop the first element and change the last one to the root position
58
59 function changeLastToRoot() {
60 global $array;
61 $length = count($array);
62 $array[0] = $array[$length - 1];
63 array_pop($array);
64 }
65
66 function adjustRootNode() {
67 global $array;
68 $curNode = $array[0]; // record the node need to adjust
69 $parent = 0; // begin from root
70 if (empty($array)) {
71 $length = 0;
72 } else {
73 $length = count($array);
74 }
75 for ($i = $parent * 2 + 1; $i < $length; $i*=2) {
76 if ($i < $length - 1 and $this->cmp($array[$i + 1], $array[$i])) {
77 $i++;
78 }
79
80 if ($this->cmp($curNode, $array[$i])) {
81 break;
82 }
83 $array[$parent] = $array[$i];
84 $parent = $i;
85 }
86 $array[$parent] = $curNode;
87 }
88
89 # return the min/max node, if no element return null
90
91 function top() {
92 global $array;
93 if (empty($array)) {
94 return null;
95 } else {
96 return $array[0];
97 }
98 }
99
100 # judge array whether has element
101
102 function isEmpty() {
103 global $array;
104 return empty($array);
105 }
106
107 #judging that how to compare
108
109 protected function cmp($node1, $node2) {
110 global $flag;
111 if ($flag) {
112 return $node1->value < $node2->value;
113 } else {
114 return $node1->value > $node2->value;
115 }
116 }
117
118 protected function swap(&$node1, &$node2) {
119 $tmp = $node1;
120 $node1 = $node2;
121 $node2 = $tmp;
122 }
123
124 }