Skip to content

Commit

Permalink
refactor(linkedlist): Add next(), prev(), value() and setvalue!() fun…
Browse files Browse the repository at this point in the history
…ctions for ListNode
  • Loading branch information
guo-yong-zhi committed Nov 6, 2024
1 parent 9197d23 commit 4e51849
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 33 deletions.
63 changes: 35 additions & 28 deletions src/linkedlist.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module LinkedList
export DoubleList, ListNode, movetofirst!, IntMap, ishead, istail, seek_head, seek_tail
export DoubleList, ListNode, movetofirst!, IntMap, next, prev, value, setvalue!, ishead, istail, seek_head, seek_tail
mutable struct ListNode{T}
value::T
prev::ListNode{T}
Expand All @@ -17,28 +17,32 @@ function ListNode{T}(value::T) where T
n
end
ListNode(value::T) where T = ListNode{T}(value)
ishead(n::ListNode) = n.prev === n
istail(n::ListNode) = n.next === n
next(n::ListNode) = n.next
prev(n::ListNode) = n.prev
value(n::ListNode) = n.value
setvalue!(n::ListNode, v) = n.value = v
ishead(n::ListNode) = prev(n) === n
istail(n::ListNode) = next(n) === n
function Base.iterate(l::ListNode, p=l) # from this node to the end
istail(p) ? nothing : (p.value, p.next)
istail(p) ? nothing : (value(p), next(p))
end
Base.IteratorSize(::Type{<:ListNode}) = Base.SizeUnknown()
Base.eltype(::Type{ListNode{T}}) where T = T
function seek_tail(n::ListNode)
while !istail(n)
n = n.next
n = next(n)
end
n
end
function seek_head(n::ListNode)
while !ishead(n)
n = n.prev
n = prev(n)
end
n
end
function Base.pop!(n::ListNode)
n.prev.next = n.next
n.next.prev = n.prev
n.prev.next = next(n)
n.next.prev = prev(n)
n
end

Expand All @@ -64,67 +68,70 @@ function DoubleList{T}(hv::T) where T
l.head.value = hv
l
end
Base.isempty(l::DoubleList) = istail(l.head.next)
head(l::DoubleList) = l.head
Base.isempty(l::DoubleList) = istail(next(head(l)))
function Base.pushfirst!(l::DoubleList, n::ListNode)
n.next = l.head.next
n.prev = l.head
l.head.next = n
n.next.prev = n
h = head(l)
hn = next(h)
n.next = hn
n.prev = h
h.next = n
hn.prev = n
n
end

Base.pop!(l::DoubleList, n::ListNode) = Base.pop!(n)
Base.popfirst!(l::DoubleList) = (@assert !isempty(l); pop!(l.head.next))
Base.pop!(l::DoubleList, n::ListNode) = pop!(n)
Base.popfirst!(l::DoubleList) = (@assert !isempty(l); pop!(next(head(l))))

function movetofirst!(l::DoubleList, n::ListNode)
pop!(l, n)
pushfirst!(l, n)
end
Base.iterate(l::DoubleList, args...) = iterate(l.head.next, args...)
Base.iterate(l::DoubleList, args...) = iterate(next(head(l)), args...)
Base.IteratorSize(::Type{<:DoubleList}) = Base.SizeUnknown()
Base.eltype(::Type{DoubleList{T}}) where T = T

function collect!(l::DoubleList, collection)
p = l.head.next
p = next(head(l))
while !istail(p)
push!(collection, p.value)
p = p.next
push!(collection, value(p))
p = next(p)
end
# @assert p === l.tail
collection
end
function collect!(l::DoubleList, collection, firstn)
p = l.head.next
p = next(head(l))
for i in 1:firstn
if istail(p)
# @assert p === l.tail
break
end
push!(collection, p.value)
p = p.next
push!(collection, value(p))
p = next(p)
end
collection
end
function collect!(filter, l::DoubleList, collection)
p = l.head.next
p = next(head(l))
while !istail(p)
v = p.value
v = value(p)
filter(v) && push!(collection, v)
p = p.next
p = next(p)
end
# @assert p === l.tail
collection
end
function collect!(filter, l::DoubleList, collection, firstn)
p = l.head.next
p = next(head(l))
for i in 1:firstn
if istail(p)
# @assert p === l.tail
break
end
v = p.value
v = value(p)
filter(v) && push!(collection, v)
p = p.next
p = next(p)
end
collection
end
Expand Down
2 changes: 1 addition & 1 deletion src/qtree_functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ function partialcollisions(qtrees::AbstractVector,
# 但要保证更prev的node在`labels`中
treenode = seek_treenode(listnode)
spindex = spacial_index(treenode)
append!(itemlist, (((label, lb) => spindex) for lb in listnode.next))
append!(itemlist, (((label, lb) => spindex) for lb in next(listnode)))
tn = treenode
while !isroot(tn)
tn = tn.parent #root不是哨兵,值需要遍历
Expand Down
6 changes: 2 additions & 4 deletions src/qtrees.jl
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,7 @@ function new_listnode_for_push(t::LinkedSpacialQTree, value::Int)
return ListNode(value)
else
n = popfirst!(cache)
n.value = value
# n.prev = n #will be assigned in pushfirst!
# n.next = n
setvalue!(n, value)
return n
end
end
Expand Down Expand Up @@ -512,7 +510,7 @@ function Base.push!(t::LinkedSpacialQTree, inds, label::Int)
end
function seek_treenode(listnode::ListNode{Int})
head = seek_head(listnode)
unsafe_pointer_to_objref(Ptr{Any}(head.value))::SpacialQTreeNode
unsafe_pointer_to_objref(Ptr{Any}(value(head)))::SpacialQTreeNode
end
function Base.empty!(t::LinkedSpacialQTree, label)
if haskey(t.map, label) && !isempty(t.map[label])
Expand Down

0 comments on commit 4e51849

Please sign in to comment.