数组队列Queue
# 使用循环队列的方式
local arrayext = require("arrayext") local Queue = {} Queue.__cname = "util.Queue" Queue.__index = Queue local ClearTypeEnum = { Reset = nil, FillNil = 1, Keep = 2, } Queue.ClearTypeEnum = ClearTypeEnum function Queue.new(capacity) local obj = {} setmetatable(obj, Queue) obj:ctor(capacity) return obj end function Queue:ctor(capacity) self.arr = {} self.capacity = capacity or 8 self.head = 1 ---当前:先加减再操作 self.tail = 1 ---后一个位置: 先操作再加减 self.count = 0 end function Queue:Clear(clearType) if self:GetCount() < 1 then return end if clearType == ClearTypeEnum.Reset then self.arr = {} elseif clearType == ClearTypeEnum.FillNil then if self.head < self.tail then for i=self.head,self.tail-1 do self.arr[i] = nil end else for i=self.head,self.capacity do self.arr[i] = nil end for i=1,self.tail-1 do self.arr[i] = nil end end end self.capacity = 0 self.head = 1 self.tail = 1 self.count = 0 end function Queue:GetCount() return self.count end function Queue:_GetMod(index) if index > self.capacity then index = index - self.capacity elseif index < 1 then index = index + self.capacity end return index end function Queue:_Expand() --注意: 交换次数为奇数次, 还要再多交换一次(把最后2个元素调整下) if self.head > 1 then local j = 1 for i=self.head,self.capacity do arrayext.Swap(self.arr, j, i) j = j + 1 end local swapCount = self.capacity - self.head + 1 if 1 == math.fmod(swapCount, 2) then arrayext.Swap(self.arr, self.capacity, self.capacity - 1) end end self.head = 1 self.tail = self.count + 1 self.capacity = self.capacity * 2 end function Queue:Enqueue(v) self.arr[self.tail] = v self.tail = self:_GetMod(self.tail + 1) self.count = self.count + 1 if self.head == self.tail then self:_Expand() end end function Queue:Dequeue() if self:GetCount() < 1 then return nil end local ret = self.arr[self.head] self.arr[self.head] = nil self.head = self:_GetMod(self.head + 1) self.count = self.count - 1 return ret end function Queue:PeekFirst() if self:GetCount() < 1 then return nil end return self.arr[self.head] end function Queue:PeekLast() if self:GetCount() < 1 then return nil end local index = self:_GetMod(self.tail - 1) return self.arr[index] end function Queue:__tostring() if self:GetCount() < 1 then return "" end local strTb = {} if self.head < self.tail then for i=self.head,self.tail-1 do table.insert(strTb, tostring(self.arr[i])) end else for i=self.head,self.capacity do table.insert(strTb, tostring(self.arr[i])) end for i=1,self.tail-1 do table.insert(strTb, tostring(self.arr[i])) end end return table.concat(strTb, ",") end function Queue:GetIterator() if nil == self.iterator then self.iterator = function(tb, k) return self:Dequeue() end end return self.iterator end return Queue