# 尝试使用Julia实现一个单链表…

#1

``````module SinglyLinkedList

abstract type Node{T} end

mutable struct DataNode{T}<:Node{T}
next::Union{DataNode{T},Nothing}
data::T
end

DataNode{T}(data::T) where T=DataNode{T}(nothing,data)

next::Union{DataNode{T},Nothing}
size::Integer

end

end

while cur.next!=nothing
cur=cur.next
end
cur.next=DataNode{T}(x)
end

if first==nothing
throw(ArgumentError("list must be non-empty"))
end
return first.data
end

prev=nothing
while cur.next!=nothing
prev=cur
cur=cur.next
end
if prev==nothing
throw(ArgumentError("list must be non-empty"))
end
prev.next=nothing
return cur.data
end

nextnode=pos.next
pos.next=DataNode{T}(x)
pos.next.next=nextnode
end

if cur==nothing
return
end
while cur.next!=nothing
nextnode=cur.next.next
cur.next=nextnode
end
end

if first==nothing
return nothing
else
return (first.data,first)
end
end

cur=cur.next
if cur==nothing
return nothing
else
return (cur.data,cur)
end
end

end``````

``````julia> using SinglyLinkedList

[]

julia> push!(h,2,3,5)
[2-> 3-> 5]

julia> pushfirst!(h,1)
[1-> 2-> 3-> 5]

julia> let
next=iterate(h)
while next!=nothing
(x,s)=next
if x==3
insert!(h,s,4)
end
next=iterate(h,s)
end
end

julia> h
[1-> 2-> 3-> 4-> 5]

julia> reverse!(h)
[5-> 4-> 3-> 2-> 1]

julia> popfirst!(h)
5

julia> while !isempty(h)
println(pop!(h))
end
1
2
3
4``````

#2

`next` 是一个 Base 函数，试着改成别的名字。

``````DataNode(data::T) where T
``````

#4
``````module SingleList
abstract type Node{T} end
mutable struct DataNode{T}<:Node{T}
data::T
tail::Node{T}
end

size::Int
tail::Node{T} #Tail接下来就是DataNode构成的单链表
last::Node{T} #存放最后一个 DataNode (尾部)
x = new{T}(0)
x.tail = x
x.last = x
end
end

true
end
false
end

else
end
end
#pushfirst还可以写的更短
end
#push的实现很巧妙，没有用条件判断
end
``````

#5

#6

``````mutable struct Node{T}
next :: Union{Node{T}, Nothing}
end

mutable struct List{T}
tail :: Node{T}
size :: Int
end

function List{T}() where {T}
tail = Node{T}(nothing, nothing)
end
``````

``````function Base.iterate(node :: Node{T}, this :: Union{Node{T}, Nothing} = node) where {T}
this == nothing ? nothing : (this, this.next)
end

function Base.getindex(node :: Node{T}, index :: Integer) where {T}
i :: Union{Integer, Nothing} = nothing
for e in zip(0 : index, node)
i, node = e
end
i == index ? node : nothing
end

function Base.setindex!(node :: Node{T}, new :: Node{T},  index :: Integer) where {T}
previous = node[index - 1]
new.next = node[index].next
previous.next = new
end

function Base.insert!(node :: Node{T}, index :: Integer, new :: Node{T}) where {T}
previous = node[index - 1]
new.next = node[index]
previous.next = new
end

function Base.deleteat!(node :: Node{T}, index :: Integer) where {T}
previous = node[index - 1]
next = node[index + 1]
previous.next = next
end
``````

``````function Base.iterate(list :: List{T}, this :: Node{T} = list.head.next) where {T}
this == list.tail ? nothing : (this.payload, this.next)
end

function Base.length(list :: List{T}) where {T}
list.size
end

function checkbound(list :: List{T}, index :: Integer) where {T}
index >= 1 && index <= length(list)
end

function Base.insert!(list :: List{T}, index :: Integer, value :: T) where {T}
checkbound(list, index) || index == length(list) + 1 ? (insert!(list.head, index, Node{T}(value, nothing)); list.size = list.size + 1) : throw(BoundsError())
end

function Base.append!(list :: List{T}, value :: T) where {T}
insert!(list, length(list) + 1, value)
end

function Base.deleteat!(list :: List{T}, index :: Integer) where {T}
checkbound(list, index) ? (deleteat!(list.head, index); list.size = list.size - 1) : throw(BoundsError())
end

function Base.getindex(list :: List{T}, index :: Integer) where {T}
end

function Base.setindex!(list :: List{T}, value :: T, index :: Integer) where {T}
checkbound(list, index) ? list.head[index] = Node{T}(value, nothing) : throw(BoundsError())
end

function Base.firstindex(list :: List{T}) where {T}
1
end

function Base.lastindex(list :: List{T}) where {T}
length(list)
end
``````

#7

#8

#9

``push!(LOAD_PATH,pwd())``

#10

#11

#12