Lua - List as Stack



The stack is an important data structure that operates on the principle of Last-In-First-Out (LIFO). It represents a collection of elements where the most recently added element takes precedence in removal. The stack class in Java offers several methods to manipulate elements e-ffectively. For example, the push method allows you to add an element to the top of the stack, while pop removes and returns the topmost element.

push method implementation

During push() operation, the element will be pushed to the end of the linked list. The prev and next references are updated accordingly.

-- push an element to the end of the list
function list:push(t)
   -- move till last node    
   if self.last then
      self.last._next = t
      t._prev = self.last
      self.last = t
   else
      -- set the node as first node
      self.first = t
      self.last = t
   end
   -- increment the length of the list
   self.length = self.length + 1
end

pop method implementation

During pop() operation, the element will be removed from the end of the linked list. The prev and next references are updated accordingly.

function list:pop()
  -- if list is empty
  if not self.last then return end
  
  local returnedValue = self.last
  
  if returnedValue._prev then
    returnedValue._prev._next = nil
    self.last = returnedValue._prev
    returnedValue._prev = nil
  else
    -- this was the only node
    self.first = nil
    self.last = nil
  end
  
  self.length = self.length - 1
  return returnedValue
end

Test Stack Operations

-- create the stack
local stack = list()

-- push values to the stack
stack:push({'A'})
stack:push({'B'})

-- print the size of the stack
print(stack:size())

-- pop top element from the stack
print(stack:pop())

-- print the updated size of the stack
print(stack.size())

-- pop top element from the stack
print(stack:pop())

Complete Example - Stack Implementation using List

Following is the complete example of a Stack implementation using a linked list.

main.lua

-- List Implementation
list = {}
list.__index = list

setmetatable(list, { __call = function(_, ...)
   local t = setmetatable({ length = 0 }, list)
      for _, v in ipairs{...} 
         do t:push(v) 
      end
      return t
   end })

-- push an element to the end of the list
function list:push(t)
   -- move till last node    
   if self.last then
      self.last._next = t
      t._prev = self.last
      self.last = t
   else
      -- set the node as first node
      self.first = t
      self.last = t
   end
   -- increment the length of the list
   self.length = self.length + 1
end

function list:pop()
  -- if list is empty
  if not self.last then return end
  
  local returnedValue = self.last
  
  if returnedValue._prev then
    returnedValue._prev._next = nil
    self.last = returnedValue._prev
    returnedValue._prev = nil
  else
    -- this was the only node
    self.first = nil
    self.last = nil
  end
  
  self.length = self.length - 1
  return returnedValue
end

function list:size()
   return self.length
end

-- create the stack
local stack = list()

-- push values to the stack
stack:push({'A'})
stack:push({'B'})

-- print the size of the stack
print("Stack Initial Size:", stack:size())

-- pop top element from the stack
print("Value Popped: ", stack:pop()[1])

-- print the updated size of the stack
print("Stack Updated Size:", stack:size())

-- pop top element from the stack
print("Value Popped: ", stack:pop()[1])

-- print the updated size of the stack
print("Stack Updated Size:", stack:size())

Output

When we run the above code, we will get the following output−

Stack Initial Size:	2
Value Popped: 	B
Stack Updated Size:	1
Value Popped: 	A
Stack Updated Size:	0
Advertisements