![](/img/trans.png)
[英]How exactly is LinkedList<T> and LinkedListNode<T> implemented in C#? And how exactly does LinkedList<T>.Remove(LinkedListNode<T>) work?
[英]How does one add a LinkedList<T> to a LinkedList<T> in C#?
人們會認為簡單的代碼
llist1.Last.Next = llist2.First;
llist2.First.Previous = llist1.Last;
會起作用,但顯然在 C# 的 LinkedList、First、Last 中,並且它們的屬性僅為 Get。
我能想到的另一種方法是
llist1.AddLast(llist2.First);
但是,這也不起作用——它失敗了,因為 llist2 的第一個節點已經在一個鏈表中。
這是否意味着我必須有一個循環將 llist2 的每個節點手動 AddLast 到 llist1? 這不會破壞鏈表的效率嗎????
是的,不幸的是,您必須循環。 這是一個 O(n) 操作 - 對於添加的每個條目 O(1)。 沒有需要調整緩沖區大小和復制等的風險 - 盡管垃圾收集當然可能會做粗略的 :) 您甚至可以編寫方便的擴展方法:
public static class LinkedListExtensions
{
public static void AppendRange<T>(this LinkedList<T> source,
IEnumerable<T> items)
{
foreach (T item in items)
{
source.AddLast(item);
}
}
public static void PrependRange<T>(this LinkedList<T> source,
IEnumerable<T> items)
{
LinkedListNode<T> first = source.First;
// If the list is empty, we can just append everything.
if (first is null)
{
AppendRange(source, items);
return;
}
// Otherwise, add each item in turn just before the original first item
foreach (T item in items)
{
source.AddBefore(first, item);
}
}
}
編輯:Erich 的評論表明為什么您可能認為這是低效的 - 為什么不通過更新第一個列表尾部的“next”指針和第二個列表頭部的“prev”指針將兩個列表連接在一起? 好吧,想想第二個列表會發生什么……它也會改變。
不僅如此,這些節點的所有權會怎樣? 現在每個本質上都是兩個列表的一部分……但是LinkedListNode<T>.List
屬性只能談論其中一個。
雖然我可以理解為什么在某些情況下您可能想要這樣做,但 .NET LinkedList<T>
類型的構建方式基本上禁止它。 我認為這個文檔評論最好地解釋了它:
LinkedList<T>)
類不支持鏈接、拆分、循環或其他會使列表處於不一致狀態的功能。
llist1 = new LinkedList<T>(llist1.Concat(llist2));
這將連接兩個列表(需要 .NET 3.5)。 缺點是它創建了一個新的 LinkedList 實例,這可能不是你想要的......你可以這樣做:
foreach(var item in llist2)
{
llist1.AddLast(item);
}
在這里你可以找到我的鏈表實現,它的連接和拆分時間為 O(1)。
為什么 .NET LinkedList 不支持 Concat 和 Split 操作?
簡短的摘要
與 .NET LinkedList 相比的優勢:
更少的內存消耗,因此與原始 .NET 實現不同,每個節點 SimpleLinkedListNode 都有三個指針(prev、next、value)而不是四個(prev、next、list、value)。
支持 O(1) 中的 Concat 和 Split 操作
支持 O(1) 中的 IEnumarable Reverse() 枚舉器 - 順便說一下,我沒有看到任何原因為什么它沒有在 .NET LinkedList 上本地提供。 適當的擴展方法需要 O(n)。
缺點:
其他:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.