你没有看错,我又无聊到写单链表了,这个写完以后,我他娘的再也不写链表了,都写吐了
1. 先上链表定义
# TODO: List struct
mutable struct ListNode{T}
value::T
next::Union{Nothing,ListNode{T}}
ListNode{T}() where T = (x=new();x.next=nothing;x)
ListNode{T}(value::T,next::Union{Nothing,ListNode{T}}) where T = new(value,next)
end
@enum ListMode begin
LIST = 0
QUEUE = 1
STACK = 2
end
mutable struct List{T}
head::ListNode{T}
tail::ListNode{T}
size::Int
mode::ListMode
end
function List{T}(mode::ListMode=LIST) where T
head = tail = ListNode{T}()
size = 0
List{T}(head,tail,0,mode)
end
# TODO: next of node
function next(node::ListNode{T}) where T
node.next
end
ListMode
------- 把List,Queue,Stack三个的行为整合在一起
2. 链表基本操作
2.1 push
# TODO: list push --- push_back
function push_next(node_1::ListNode{T},node_new::ListNode{T}) where T
node_2 = node_1.next
node_new.next = node_2
node_1.next = node_new
end
function push_back(list::List{T},node::ListNode{T}) where T
list.tail = push_next(list.tail,node)
list.size += 1
list
end
function push_back(list::List{T},value::T) where T
list.tail = push_next(list.tail,ListNode{T}(value,nothing))
list.size += 1
list
end
function push_front(list::List{T},node::ListNode{T}) where T
push_next(list.head,node)
list.size += 1
list
end
function push_front(list::List{T},value::T) where T
push_next(list.head,ListNode{T}(value,nothing))
list.size += 1
list
end
整合push
function push(list::List{T},node::ListNode{T}) where T
if list.mode == LIST || list.mode == QUEUE
push_back(list,node)
elseif list.mode == STACK
push_front(list,node)
end
end
function push(list::List{T},value::T) where T
push(list,ListNode{T}(value,nothing))
end
2.2 pop
# TODO: list pop --- pop_back
function pop_next(node_1::ListNode{T}) where T
node_2 = node_1.next
if node_2 != nothing
node_3 = node_2.next
node_1.next = node_3
end
node_1
end
function pop_back(list::List{T}) where T
current_node = list.head
while current_node.next != list.tail
current_node = next(current_node)
end
list.size -= 1
list.tail = pop_next(current_node)
end
# TODO: list pop --- pop_front
function pop_front(list::List{T}) where T
list.size -= 1
pop_next(list.head)
end
整合 pop
function pop(list::List{T}) where T
if list.size != 0
if list.mode == QUEUE || list.mode == STACK
pop_front(list)
elseif list.mode == LIST
pop_back(list)
end
end
end
特殊情况
function pop(list::List{T},node::ListNode{T}) where T
current_node = list.head
while current_node.next != node
current_node = next(current_node)
end
list.size -= 1
pop_next(current_node)
end
怎么没有pop(list,value)
的函数定义?我觉得这个放在高阶函数remove里更合适
3.高阶函数
3.1 filter
function Base.filter(fn::Function,list::List{T}) where T
__filter = function __filter(node::Union{Nothing,ListNode{T}},res::List{T}) where T
# edge
if node == nothing
res
else
if fn(node.value)
__filter(node.next,push(res,node))
else
__filter(node.next,res)
end
end
end
__filter(list.head.next,List{T}())
end
3.2 map
function Base.map(fn::Function,list::List{T}) where T
__map = function __map(node::Union{Nothing,ListNode{T}},res::List{T}) where T
if node == nothing
res
else
new_node = ListNode{T}(fn(node.value),nothing)
__map(node.next,push(res,new_node))
end
end
__map(list.head.next,List{T}())
end
3.3 reduce
function Base.reduce(fn::Function,list::List{T};init=0::T) where T
__reduce = function __reduce(node::Union{Nothing,ListNode{T}},res::T) where T
if node == nothing
res
else
__reduce(node.next,fn(res,node.value))
end
end
__reduce(list.head.next,init)
end
3.4 remove
function remove(fn::Function,list::List{T}) where T
__remove = function __remove(node::Union{Nothing,ListNode{T}},res::List{T}) where T
if node == nothing
res
else
if fn(node.value)
__remove(node.next,res)
else
__remove(node.next,push(res,node))
end
end
end
__remove(list.head.next,List{T}())
end
3.5 foreach
function Base.foreach(fn::Function,list::List{T}) where T
__foreach = function __foreach(node::Union{Nothing,ListNode{T}}) where T
if node != nothing
fn(node.value)
__foreach(node.next)
end
end
__foreach(list.head.next)
end
4.迭代器 iterate
function Base.iterate(list::List{T}) where T
list.head.next.value,list.head.next
end
function Base.iterate(list::List{T},state::ListNode{T}) where T
state.next == nothing ? nothing : (state.next.value,state.next)
end
写在最后
有哪位能把我的链表用Iterator这个库实现惰性,我实在力不从心了