在F#中實現可變數據結構的好方法是什麼?我問的原因是因爲我想回去實現我在本學期學習的算法類中學到的數據結構(跳過列表,展開樹,融合樹,y-fast嘗試,van Emde Boas樹等等),這是一門純粹的理論課程,沒有任何編碼,我想我也可以嘗試學習F#,而我正在做這件事。我知道我「應該」使用手指樹來獲得功能性語言的splay tree功能,並且我應該採取懶惰的方式來獲得跳過列表功能等,但是我想在嘗試之前弄清楚基本知識。玩純粹的功能實現。F#中可變數據結構(例如,跳過列表,展示樹)的正確方法是什麼?
有很多關於如何在F#中完成功能數據結構的例子,但是關於如何做可變數據結構沒有太多的例子,所以我開始將雙鏈表here修改成允許插入和刪除任何地方。我的計劃是把它變成一個跳過列表,然後爲我想實現的樹結構使用類似的結構(有區別的記錄聯合)。在我開始一些更實質的事情之前,有沒有更好的方式在F#中做這樣的可變結構?我應該只使用記錄,而不用歧視工會嗎?我應該用班級嗎?這個問題「甚至沒有錯」?我是否應該在C#中做可變結構,並且在我想將它們與純函數進行比較之前不要深入F#中?
而且,如果DU記錄是我想要的,我可以寫更好還是更慣用的代碼?似乎這裏有很多冗餘,但我不知道如何擺脫它。
module DoublyLinkedList =
type 'a ll =
| None
| Node of 'a ll_node
and 'a ll_node = {
mutable Prev: 'a ll;
Element : 'a ;
mutable Next: 'a ll;
}
let insert x l =
match l with
| None -> Node({ Prev=None; Element=x; Next=None })
| Node(node) ->
match node.Prev with
| None ->
let new_node = { Prev=None; Element=x; Next=Node(node)}
node.Prev <- Node(new_node)
Node(new_node)
| Node(prev_node) ->
let new_node = { Prev=node.Prev; Element=x; Next=Node(node)}
node.Prev <- Node(new_node)
prev_node.Next <- Node(new_node)
Node(prev_node)
let rec nth n l =
match n, l with
| _,None -> None
| _,Node(node) when n > 0 -> nth (n-1) node.Next
| _,Node(node) when n < 0 -> nth (n+1) node.Prev
| _,Node(node) -> Node(node) //hopefully only when n = 0 :-)
let rec printLinkedList head =
match head with
| None ->()
| Node(x) ->
let prev = match x.Prev with
| None -> "-"
| Node(y) -> y.Element.ToString()
let cur = x.Element.ToString()
let next = match x.Next with
| None -> "-"
| Node(y) -> y.Element.ToString()
printfn "%s, <- %s -> %s" prev cur next
printLinkedList x.Next
另請參見http://cs.hubfs.net/forums/thread/14029.aspx – Brian 2010-05-08 22:04:04
除了散列表和鏈表之外,我個人發現不可變數據結構比可變對象更容易實現 - 特別是樹木。你的旅費可能會改變。 – Juliet 2010-05-10 03:48:50
朱麗葉:數組呢?當然這些更容易實現可變。 – Gabe 2010-05-10 04:00:39