lua是一个简洁、轻量、可扩展的脚本语言,在国内,通常在游戏行业的程序员对它比较熟悉。在这篇文章中想用lua中的table实现一个链表。
首先,很简单地创建一个空链表list,空链表中,list持有first,last,count三个key,分别对应第一个,最后一个和链表节点个数:
function list.create()
local list = {}
list.first = nil
list.last = nil
list.count = 0
return list
end
在创建链表的方法中,我们就能很清晰的知道链表的大致情况,比如,获取链表的长度,直接return list.count即可,判空同理。
其次,实现一些链表常用方法,push:添加到链表末尾,在这个方法中,形参list是你的目标链表,value是你要添加的节点数据,可以是各种类型,包括table,同时,我们给链表的每个节点添加了next,pre两个key,分别指向下一个节点和上一节点,其实,如果只是实现单向链表,next,pre只需要一个就好了,这里我们两个都写出来了:
function list.push(list, value)
local item = {}
item.value = value
-- 当前空队列
if list.first == nil then
list.first = item
list.last = item
list.count = 1
else
-- 非空队列,添加至末尾
list.last.next = item
item.pre = list.last
list.last = item
list.count = list.count + 1
end
end`
接着我们在实现insert方法,插入一个节点至链表开头,key解释参考上面:
`--- 插入一个元素到开头
function list.insert(list, value)
local item = {}
item.value = value
if list.first == nil then
list.first = item
list.last = item
list.count = list.count + 1
else
item.next = list.first
list.first.pre = item
list.first = item
list.count = list.count + 1
end
end
有了添加节点的方法,当然就有删除节点方法,removeFirst和removeLast:
function list.removeFirst(list)
local val = nil
-- 空栈
if list.count == 0 then
-- 只有一个元素
elseif list.count == 1 then
val = list.first.value
list.first = nil
list.last = nil
list.count = 0
-- 多个元素,第一个有值
elseif list.first ~= nil then
-- 取值
val = list.first.value
-- 头指向第二个
list.first = list.first.next
-- 非空
if list.first ~= nil then
list.first.pre = nil
list.count = list.count - 1
else
list.count = 0
end
end
return val
end
--- 删除最后一个元素
function list.removeLast(list)
local item = list.last
if list.last ~= nil then
-- 如果本身只有一个元素
if list.last.pre == nil then
list.first = nil
list.last = nil
list.count = 0
else
-- 不只一个元素
list.last = list.last.pre
list.last.next = nil
list.count = list.count - 1
end
end
if item ~= nil then
return item.value
end
end
既然是一个顺序链表,那在业务端必然有想要链表每一结点都想操作的方法,基于此,我们可以再写一个方法,实现链表中的每一个节点顺序调用同一个方法(逆序调用同理),形参func为用户传入想要执行的函数:
function list.foreach(list, func)
local temp = list.first
local continue = true
while temp ~= nil and continue do
continue = func(temp.value)
if not continue then
break
end
temp = temp.next
end
end
一个用lua实现的链表到这就差不多结束了,在我看来,相比于c++实现的链表,lua的语法逻辑更为清晰明了,拓展性也更强,一个节点不需要局限于某一种类型,完全由用户自定义。
完整代碼:
dump--自定義輸出表方法
local stack_ = {}
local function createStack( ... )
local t = {};
t._count = 0
t._first = nil
t._end = nil
t._next = nil
t._last = nil
--返回栈顶的对象
function t:peek( ... )
return t._first.value
end
--压栈
function t:push( ... )
t._count = t._count + 1
local node = {}
node.value = {...}
node._next = nil
node._last = t._first
if not t._next then
t._next = node
t._first = node
t._end = node
else
t._first._next = node
t._first = node
end
dump(t._first.value,"插入的value == ")
end
--删除并返回栈顶的对象
function t:pop()
t._count = t._count - 1
local value = t._first.value
if not t._first._last then
t._first = nil
t._end = nil
t._next = nil
t._last = nil
else
t._first._last._next = nil
t._first = t._first._last
end
return value
end
--获取堆栈长度
function t:getn( ... )
return t._count
end
--打印堆栈
function t:print( ... )
local node = t
while(node._next)do
dump(node._next.value,"value == ")
node = node._next
end
end
return t;
end
stack_.createStack = createStack
return stack_
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。