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_

柚子
1 声望0 粉丝