如何在Julia中实现SingleLinkedList

如何在Julia中实现SingleLinkedList,julia,Julia,我正在学习TAD,但是,我不太懂语法,这就是为什么创建一个列表对我来说太难了,但是我理解它是如何工作的,比如TAD,请,有人可以告诉我如何实现这个TAD(链表),并给出基本的说明和描述 abstract type AbstractList{T} end abstract type AbstractNode{T} end mutable struct Nodo{T} <: AbstractNode{T} value ::T next ::Nodo{T} Nodo{T

我正在学习TAD,但是,我不太懂语法,这就是为什么创建一个列表对我来说太难了,但是我理解它是如何工作的,比如TAD,请,有人可以告诉我如何实现这个TAD(链表),并给出基本的说明和描述

abstract type AbstractList{T} end
abstract type AbstractNode{T} end

mutable struct Nodo{T} <: AbstractNode{T}
    value ::T
    next ::Nodo{T}
    Nodo{T}() where T =(x=new();x;x.next=x)
    Nodo{T}(v,n) where T =new(v,n)
end

mutable struct LList{T} <: AbstractList{T}
    first ::Nodo{T}
    LList{T}() where T =new(Nodo{T}())
end

Lista=LList;

function Append(lista,value)
    current=Nodo(value,new(Nodo()))
    if Lista.size==0
        lista.head=current
    else
        MyNode=Lista.first;
        while MyNode.next!=nothing
            MyNode=MyNode.next;
        MyNode.next=current;
        end
    end
    Lista.size+=1
end

Append(Lista,2)
抽象类型抽象列表{T}end
抽象类型AbstractNode{T}end

mutable struct Nodo{T}您的代码中混合了一些概念,因此为了帮助您,我将使用其中的一个概念向您展示如何实现链接列表。代码如下:

abstract type AbstractList{T} end
abstract type AbstractNode{T} end

mutable struct Nodo{T} <: AbstractNode{T}
    value::T
    next::Union{Nodo{T}, Nothing}
end

mutable struct LList{T} <: AbstractList{T}
    head::Union{Nodo{T}, Nothing}
    LList{T}() where T = new{T}(nothing)
end

function Base.push!(lista::LList, value)
    new_nodo = Nodo(value, nothing)
    if isnothing(lista.head)
        lista.head = new_nodo
    else    
        current_nodo = lista.head
        while !isnothing(current_nodo.next)
            current_nodo = current_nodo.next
        end
        current_nodo.next = new_nodo
    end
    return lista
end
一些评论:

  • 我使用
    Union
    表示一个对象可以不包含引用(
    Nothing
    ),也可以包含对下一个对象的引用(
    Nodo{T}
  • LList{T}()中,T=new{T}(nothing)
    我们只定义了一个内部构造函数,因为它不带任何参数,所以我使用
    new{T}
    来创建
    LList{T}
    对象的实例,该对象的值设置为
    nothing
    (因为它还没有节点)
  • 我使用
    Base.push因为这是向集合添加项的函数的标准名称<代码>基。
    用于向标准函数添加方法;因此,稍后我还要编写
    lista::LList
    ,以确保此方法特定于您的
    LList{T}
    类型
  • 正如您在代码中看到的,不需要“dummy”节点(正如您的代码中所显示的那样),因为您只需使用
    nothing
    value来跟踪列表的末尾


我希望从这一点开始,您将能够向您的
LList
对象添加其他方法。

Bogumil答案的一个稍微不同的版本是使用未定义的字段

abstract type AbstractList{T} end
abstract type AbstractNode{T} end

mutable struct Nodo{T} <: AbstractNode{T}
    value::T
    next::Nodo{T}
    function Nodo(v::T) where T
        n = new{T}()
        n.value = v
        return n
    end
end

mutable struct LList{T} <: AbstractList{T}
    head::Nodo{T}
    LList{T}() where T = new{T}()
end

function Base.push!(lista::LList, value)
    new_nodo = Nodo(value)
    if isdefined(lista, :head)
        current_nodo = lista.head
        while isdefined(current_nodo, :next)
            current_nodo = current_nodo.next
        end
        current_nodo.next = new_nodo
    else
        lista.head = new_nodo
    end

    return lista
end
这种方法不引入联合字段,但会使整个代码更加脆弱,因为您需要在
nodo.next
isdefined(nodo,:next)
符号之间切换。“TAD”是什么意思?我假设为ADT(抽象数据类型)。啊,tipo abstract de datos!
abstract type AbstractList{T} end
abstract type AbstractNode{T} end

mutable struct Nodo{T} <: AbstractNode{T}
    value::T
    next::Nodo{T}
    function Nodo(v::T) where T
        n = new{T}()
        n.value = v
        return n
    end
end

mutable struct LList{T} <: AbstractList{T}
    head::Nodo{T}
    LList{T}() where T = new{T}()
end

function Base.push!(lista::LList, value)
    new_nodo = Nodo(value)
    if isdefined(lista, :head)
        current_nodo = lista.head
        while isdefined(current_nodo, :next)
            current_nodo = current_nodo.next
        end
        current_nodo.next = new_nodo
    else
        lista.head = new_nodo
    end

    return lista
end
julia> lista=LList{Int}()
LList{Int64}(#undef)

julia> push!(lista, 1)
LList{Int64}(Nodo{Int64}(1, #undef))

julia> push!(lista, 2)
LList{Int64}(Nodo{Int64}(1, Nodo{Int64}(2, #undef)))

julia> push!(lista, 3)
LList{Int64}(Nodo{Int64}(1, Nodo{Int64}(2, Nodo{Int64}(3, #undef))))