Create deque.lua

This commit is contained in:
PeaAshMeter 2025-08-15 05:52:38 +03:00
parent 7ceebbb411
commit 0993b03088

121
lib/utils/deque.lua Normal file
View File

@ -0,0 +1,121 @@
---@class Deque
---@field private first integer
---@field private last integer
---@field private _data table<integer, any>
local Deque = {}
Deque.__index = Deque
---Создать пустую очередь
---@return Deque
local function new()
---@type Deque
local self = setmetatable({
first = 1,
last = 0,
_data = {},
}, Deque)
return self
end
---Количество элементов
---@return integer
function Deque:size()
return self.last - self.first + 1
end
---Пуста ли очередь
---@return boolean
function Deque:is_empty()
return self.first > self.last
end
---Добавить в начало
---@param value any
---@return Deque self
function Deque:push_front(value)
self.first = self.first - 1
self._data[self.first] = value
return self
end
---Добавить в конец
---@param value any
---@return Deque self
function Deque:push_back(value)
self.last = self.last + 1
self._data[self.last] = value
return self
end
---Забрать из начала
---@return any
function Deque:pop_front()
if self.first > self.last then return nil end
local value = self._data[self.first]
self._data[self.first] = nil
self.first = self.first + 1
return value
end
---Забрать из конца
---@return any
function Deque:pop_back()
if self.first > self.last then return nil end
local value = self._data[self.last]
self._data[self.last] = nil
self.last = self.last - 1
return value
end
---Подсмотреть начало
---@return any
function Deque:peek_front()
if self.first > self.last then return nil end
return self._data[self.first]
end
---Подсмотреть конец
---@generic T
---@return T|nil
function Deque:peek_back()
if self.first > self.last then return nil end
return self._data[self.last]
end
---Очистить очередь
function Deque:clear()
-- Полная очистка таблицы для GC
for i = self.first, self.last do
self._data[i] = nil
end
self.first, self.last = 1, 0
end
---Итератор по значениям слева направо
---@return fun():any
function Deque:values()
local i = self.first
return function()
if i <= self.last then
local v = self._data[i]
i = i + 1
return v
end
end
end
---Преобразовать в массив
---@return any[]
function Deque:to_array()
local n = self:size()
local arr = {}
if n <= 0 then return arr end
local j = 1
for i = self.first, self.last do
arr[j] = self._data[i]
j = j + 1
end
return arr
end
return { new = new }