优先队列PriorityQueue
1 PriorityQueue = PriorityQueue or {} 2 3 --[[ 4 1 5 / \ 6 2 3 7 / \ / \ 8 4 5 6 7 9 / 10 8 11 2的子节点: 2*2和2*2+1, 3的子节点3*2和3*2+1 12 反过来: 5的父节点floor(5/2), 6的父节点floor(6/3) 13 ]] 14 15 function PriorityQueue.new(compFunc) 16 local inst = { 17 _cname = "lang.PriorityQueue", 18 } 19 20 local arr = {} 21 local len = 0 22 23 local function swap(index1, index2) 24 local t = arr[index1] 25 arr[index1] = arr[index2] 26 arr[index2] = t 27 end 28 29 function inst:count() 30 return len 31 end 32 33 function inst:clear() 34 for i=1,len do 35 arr[i] = nil 36 end 37 len = 0 38 end 39 40 function inst:push(v) 41 len = len + 1 42 arr[len] = v 43 local temp = len 44 while temp > 1 do 45 local parent = math.floor(temp / 2) 46 if compFunc(arr[temp], arr[parent]) then 47 print("push swap: ", a, ": ", temp, parent, " value: ", arr[temp], arr[parent]) 48 swap(temp, parent) 49 temp = parent 50 else 51 break 52 end 53 end 54 end 55 56 function inst:pop() 57 if len <= 0 then return end 58 59 local ret = arr[1] 60 arr[1] = nil 61 if len > 1 then 62 swap(len, 1) 63 end 64 len = len - 1 65 66 local temp = 1 67 while true do 68 local lChild = temp * 2 69 if lChild > len then break end 70 71 local rChild = lChild + 1 72 if rChild > len then 73 if not compFunc(arr[temp], arr[lChild]) then 74 swap(temp, lChild) 75 temp = lChild 76 else 77 break 78 end 79 else 80 local lValue = arr[lChild] 81 local rValue = arr[rChild] 82 if lValue > rValue then --和大的交换 83 if not compFunc(arr[temp], arr[lChild]) then 84 swap(temp, lChild) 85 temp = lChild 86 else 87 break 88 end 89 else 90 if not compFunc(arr[temp], arr[rChild]) then 91 swap(temp, rChild) 92 temp = rChild 93 else 94 break 95 end 96 end 97 end 98 end 99 return ret 100 end 101 102 function inst:peek() 103 if len <= 0 then return nil end 104 local v = arr[1] 105 return v 106 end 107 108 function inst:copyTo(dst) 109 assert("table" == type(dst), "copyTo: dst not table or Stack") 110 if "lang.PriorityQueue" == dst._cname then 111 for i=1,len do 112 dst:push(arr[i]) 113 end 114 else 115 for i=1,len do 116 table.insert(dst, arr[i]) 117 end 118 end 119 end 120 121 function inst:__tostring() 122 if len <= 0 then return "" end 123 local strTb = {} 124 local pq = PriorityQueue(compFunc) 125 self:copyTo(pq) 126 while pq:count() > 0 do 127 table.insert(strTb, pq:pop()) 128 end 129 return table.concat(strTb, ",") 130 end 131 132 function inst:__len() 133 return len 134 end 135 136 function inst:__index(k) 137 error("PriorityQueue: invalid member: " .. k) 138 end 139 140 function inst:__newindex(k, v) 141 error("PriorityQueue: add member error: " .. k) 142 end 143 144 setmetatable(inst, inst) 145 return inst 146 end 147 148 function PriorityQueue.__call(self, compFunc) 149 return PriorityQueue.new(compFunc) 150 end 151 setmetatable(PriorityQueue, PriorityQueue)
测试代码:
1 local function Test1() 2 local q = PriorityQueue(function(a, b) 3 return a > b 4 end) 5 assert(0 == q:count(), "count error") 6 assert("" == tostring(q), "") 7 8 q:push(3) 9 assert(1 == q:count(), "push error") 10 assert("3" == tostring(q), "") 11 12 q:push(1) 13 assert(2 == q:count(), "push error") 14 assert(3 == q:peek(), "peek error") 15 assert("3,1" == tostring(q), "") 16 17 q:push(2) 18 assert(3 == q:count(), "push error") 19 assert(3 == q:peek(), "peek error") 20 assert("3,2,1" == tostring(q), "") 21 22 assert(3 == q:pop(), "pop error") 23 assert(2 == q:count(), "pop error") 24 assert("2,1" == tostring(q), "") 25 26 assert(2 == q:pop(), "pop error") 27 assert(1 == q:count(), "pop error") 28 assert("1" == tostring(q), "") 29 30 assert(1 == q:pop(), "pop error") 31 assert(0 == q:count(), "pop error") 32 assert("" == tostring(q), "") 33 end 34 35 Test1()
参考:
https://www.cnblogs.com/wxgblogs/p/5727026.html