forked from NewLifeX/X
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
198 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace NewLife.Collections | ||
{ | ||
/// <summary>双向链表</summary> | ||
/// <typeparam name="T"></typeparam> | ||
public class LinkList<T> : ICollection<T> | ||
{ | ||
#region 属性 | ||
/// <summary>头部</summary> | ||
public LinkNode<T> Head { get; private set; } | ||
|
||
/// <summary>尾部</summary> | ||
public LinkNode<T> Tail { get; private set; } | ||
|
||
private Int32 _Count; | ||
/// <summary>元素个数</summary> | ||
public Int32 Count { get => _Count; private set => _Count = value; } | ||
|
||
Boolean ICollection<T>.IsReadOnly => false; | ||
#endregion | ||
|
||
#region 方法 | ||
/// <summary>添加项</summary> | ||
/// <param name="item"></param> | ||
public void Add(T item) | ||
{ | ||
var node = new LinkNode<T>(item); | ||
|
||
if (Head == null) | ||
Head = Tail = node; | ||
else | ||
node.InsertAfter(Tail); | ||
|
||
Interlocked.Increment(ref _Count); | ||
} | ||
|
||
/// <summary>删除项</summary> | ||
/// <param name="item"></param> | ||
/// <returns></returns> | ||
public Boolean Remove(T item) | ||
{ | ||
for (var node = Head; node != null; node = node.Next) | ||
{ | ||
if (Object.Equals(node.Value, item)) | ||
{ | ||
node.Remove(); | ||
|
||
Interlocked.Decrement(ref _Count); | ||
|
||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary>清空链表</summary> | ||
public void Clear() | ||
{ | ||
Head = Tail = null; | ||
_Count = 0; | ||
} | ||
|
||
/// <summary>是否包含</summary> | ||
/// <param name="item"></param> | ||
/// <returns></returns> | ||
public Boolean Contains(T item) | ||
{ | ||
for (var node = Head; node != null; node = node.Next) | ||
{ | ||
if (Object.Equals(node.Value, item)) return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary>拷贝到数组</summary> | ||
/// <param name="array"></param> | ||
/// <param name="arrayIndex"></param> | ||
public void CopyTo(T[] array, Int32 arrayIndex) | ||
{ | ||
var k = 0; | ||
for (var node = Head; node != null; node = node.Next, k++) | ||
{ | ||
array[arrayIndex] = node.Value; | ||
} | ||
} | ||
|
||
/// <summary>枚举</summary> | ||
/// <returns></returns> | ||
public IEnumerator<T> GetEnumerator() | ||
{ | ||
for (var node = Head; node != null; node = node.Next) | ||
{ | ||
yield return node.Value; | ||
} | ||
} | ||
|
||
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } | ||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System; | ||
|
||
namespace NewLife.Collections | ||
{ | ||
/// <summary>双链表节点</summary> | ||
/// <typeparam name="T"></typeparam> | ||
public class LinkNode<T> | ||
{ | ||
#region 属性 | ||
/// <summary>数值</summary> | ||
public T Value { get; set; } | ||
|
||
/// <summary>前一个</summary> | ||
public LinkNode<T> Prev { get; set; } | ||
|
||
/// <summary>下一个</summary> | ||
public LinkNode<T> Next { get; set; } | ||
#endregion | ||
|
||
#region 构造 | ||
/// <summary>实例化一个双链表节点</summary> | ||
public LinkNode() { } | ||
|
||
/// <summary>实例化一个双链表节点</summary> | ||
/// <param name="value"></param> | ||
public LinkNode(T value) { Value = value; } | ||
#endregion | ||
|
||
#region 方法 | ||
/// <summary>在指定节点之后插入</summary> | ||
/// <param name="after"></param> | ||
public void InsertAfter(LinkNode<T> after) | ||
{ | ||
Prev = after ?? throw new ArgumentNullException(nameof(after)); | ||
Next = after.Next; | ||
|
||
after.Next = this; | ||
if (Next != null) Next.Prev = this; | ||
} | ||
|
||
/// <summary>在指定节点之前插入</summary> | ||
/// <param name="before"></param> | ||
public void InsertBefore(LinkNode<T> before) | ||
{ | ||
Next = before ?? throw new ArgumentNullException(nameof(before)); | ||
Prev = before.Prev; | ||
|
||
before.Prev = this; | ||
if (Prev != null) Prev.Next = this; | ||
} | ||
|
||
/// <summary>移除节点</summary> | ||
public void Remove() | ||
{ | ||
if (Prev != null) Prev.Next = Next; | ||
if (Next != null) Next.Prev = Prev; | ||
|
||
Prev = this; | ||
Next = this; | ||
} | ||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters