LinkedList为双向循环链表,链表的定义请自行百度;先贴一下节点类:
// Note following class is not serializable since we customized the serialization of LinkedList.
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class LinkedListNode<T> {
/// <summary>
/// 自身所属的链表
/// </summary>
internal LinkedList<T> list;
/// <summary>
/// 后继节点
/// </summary>
internal LinkedListNode<T> next;
/// <summary>
/// 前驱节点
/// </summary>
internal LinkedListNode<T> prev;
/// <summary>
/// 自身储存的数据
/// </summary>
internal T item;
public LinkedListNode( T value) {
this.item = value;
}
internal LinkedListNode(LinkedList<T> list, T value) {
this.list = list;
this.item = value;
}
public LinkedList<T> List {
get { return list;}
}
public LinkedListNode<T> Next {
//当后继节点为空或自身的后继节点为链表头节点时
get { return next == null || next == list.head? null: next;}
}
public LinkedListNode<T> Previous {
//当前驱节点为空或者自身为链表头节点时
get { return prev == null || this == list.head? null: prev;}
}
public T Value {
get { return item;}
set { item = value;}
}
internal void Invalidate() {
list = null;
next = null;
prev = null;
}
}
LinkedListNode类内部保存有前驱节点prev和后继节点next以及自身存储数据item,且持有自身属于的链表list。
字段:
// This LinkedList is a doubly-Linked circular list.
internal LinkedListNode<T> head; //头结点
internal int count; //链表元素数量
internal int version;
private Object _syncRoot;
#if !SILVERLIGHT
private SerializationInfo siInfo; //A temporary variable which we need during deserialization.
#endif
// names for serialization
const String VersionName = "Version";
const String CountName = "Count";
const String ValuesName = "Data";
属性:
/// <summary>
/// 获取链表数量
/// </summary>
public int Count {
get { return count;}
}
/// <summary>
/// 获取头节点
/// </summary>
public LinkedListNode<T> First {
get { return head;}
}
/// <summary>
/// 获取尾节点
/// </summary>
public LinkedListNode<T> Last {
get { return head == null? null: head.prev;}
}
bool ICollection<T>.IsReadOnly {
get { return false; }
}
AddAfter函数和AddBefore函数:
/// <summary>
/// 插入到指定的节点后
/// </summary>
/// <param name="node">指定的节点</param>
/// <param name="value">待插入的数据</param>
/// <returns></returns>
public LinkedListNode<T> AddAfter(LinkedListNode<T> node, T value) {
ValidateNode(node);
LinkedListNode<T> result = new LinkedListNode<T>(node.list, value);
InternalInsertNodeBefore(node.next, result);
return result;
}
/// <summary>
/// 插入到指定的节点后
/// </summary>
/// <param name="node">指定的节点</param>
/// <param name="newNode">待插入的节点</param>
public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode) {
ValidateNode(node);
ValidateNewNode(newNode);
InternalInsertNodeBefore(node.next, newNode);
newNode.list = this;
}
/// <summary>
/// 插入到指定的节点前
/// </summary>
/// <param name="node">指定的节点</param>
/// <param name="value">待插入的数据</param>
/// <returns></returns>
public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value) {
ValidateNode(node);
LinkedListNode<T> result = new LinkedListNode<T>(node.list, value);
InternalInsertNodeBefore(node, result);
if ( node == head) {
head = result;
}
return result;
}
/// <summary>
/// 插入到指定的节点前
/// </summary>
/// <param name="node">指定的节点</param>
/// <param name="newNode">待插入的节点</param>
public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) {
ValidateNode(node);
ValidateNewNode(newNode);
InternalInsertNodeBefore(node, newNode);
newNode.list = this;
if ( node == head) {
head = newNode;
}
}
本质上调用了InternalInsertNodeBefore函数,ValidateNode函数和ValidateNewNode均为检查节点函数;其函数分别实现如下:
/// <summary>
/// 检查新节点
/// </summary>
/// <param name="node"></param>
internal void ValidateNewNode(LinkedListNode<T> node) {
if (node == null) {
throw new ArgumentNullException("node");
}
if ( node.list != null) {
throw new InvalidOperationException(SR.GetString(SR.LinkedListNodeIsAttached));
}
}
/// <summary>
/// 检查节点
/// </summary>
/// <param name="node">待检查的节点</param>
internal void ValidateNode(LinkedListNode<T> node) {
if (node == null) {
throw new ArgumentNullException("node");
}
if ( node.list != this) {
throw new InvalidOperationException(SR.GetString(SR.ExternalLinkedListNode));
}
}
InternalInsertNodeBefore函数实现如下:
/// <summary>
/// 将指定的节点插入待指定的节点前
/// </summary>
/// <param name="node">指定的节点</param>
/// <param name="newNode">待插入的节点</param>
private void InternalInsertNodeBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) {
//新节点的后继节点指向指定的节点
newNode.next = node;
//新节点的前驱节点指定指定的节点的前驱节点
newNode.prev = node.prev;
//指定的节点前驱节点的后继节点执行新节点
node.prev.next = newNode;
//指定的节点的前驱节点指向新节点
node.prev = newNode;
version++;
count++;
}
AddFirst函数和AddLast函数:
/// <summary>
/// 添加数据为头部
/// </summary>
/// <param name="value">待添加的数据</param>
/// <returns></returns>
public LinkedListNode<T> AddFirst(T value) {
LinkedListNode<T> result = new LinkedListNode<T>(this, value);
if (head == null) {
InternalInsertNodeToEmptyList(result);
}
else {
InternalInsertNodeBefore( head, result);
head = result;
}
return result;
}
/// <summary>
/// 添加节点为头部
/// </summary>
/// <param name="node">待添加的节点</param>
public void AddFirst(LinkedListNode<T> node) {
ValidateNewNode(node);
if (head == null) {
InternalInsertNodeToEmptyList(node);
}
else {
InternalInsertNodeBefore( head, node);
head = node;
}
node.list = this;
}
/// <summary>
/// 添加数据为尾部
/// </summary>
/// <param name="value">待添加的数据</param>
/// <returns></returns>
public LinkedListNode<T> AddLast(T value) {
LinkedListNode<T> result = new LinkedListNode<T>(this, value);
if (head== null) {
InternalInsertNodeToEmptyList(result);
}
else {
InternalInsertNodeBefore( head, result);
}
return result;
}
/// <summary>
/// 添加节点为头部
/// </summary>
/// <param name="node">待添加的节点</param>
public void AddLast(LinkedListNode<T> node) {
ValidateNewNode(node);
if (head == null) {
InternalInsertNodeToEmptyList(node);
}
else {
InternalInsertNodeBefore( head, node);
}
node.list = this;
}
其中InternalInsertNodeToEmptyList函数实现如下:
/// <summary>
/// 将指定的节点插入到空链表
/// </summary>
/// <param name="newNode">待插入的节点</param>
private void InternalInsertNodeToEmptyList(LinkedListNode<T> newNode) {
Debug.Assert( head == null && count == 0, "LinkedList must be empty when this method is called!");
newNode.next = newNode;
newNode.prev = newNode;
head = newNode;
version++;
count++;
}
Remove及其相关函数:
/// <summary>
/// 移除符合指定数据的节点
/// </summary>
/// <param name="value">指定的数据</param>
/// <returns></returns>
public bool Remove(T value) {
LinkedListNode<T> node = Find(value);
if (node != null) {
InternalRemoveNode(node);
return true;
}
return false;
}
/// <summary>
/// 移除指定节点
/// </summary>
/// <param name="node">指定的节点</param>
public void Remove(LinkedListNode<T> node) {
ValidateNode(node);
InternalRemoveNode(node);
}
/// <summary>
/// 移除头节点
/// </summary>
public void RemoveFirst() {
if ( head == null) { throw new InvalidOperationException(SR.GetString(SR.LinkedListEmpty)); }
InternalRemoveNode(head);
}
/// <summary>
/// 移除尾节点
/// </summary>
public void RemoveLast() {
if ( head == null) { throw new InvalidOperationException(SR.GetString(SR.LinkedListEmpty)); }
InternalRemoveNode(head.prev);
}
而InternalRemoveNode函数实现如下:
/// <summary>
/// 移除指定的节点
/// </summary>
/// <param name="node">待删除的节点</param>
internal void InternalRemoveNode(LinkedListNode<T> node) {
Debug.Assert( node.list == this, "Deleting the node from another list!");
Debug.Assert( head != null, "This method shouldn't be called on empty list!");
if ( node.next == node) {
Debug.Assert(count == 1 && head == node, "this should only be true for a list with only one node");
head = null;
}
else {
//node的后继节点的前驱节点指向node的前驱节点
node.next.prev = node.prev;
//node的前驱节点的后继节点指向node的后继节点
node.prev.next = node.next;
//若node为头结点,则头结点的后继节点为头结点
if ( head == node) {
head = node.next;
}
}
node.Invalidate();
count--;
version++;
}
引用一张图大致说一下节点的引用情况:
源码为.net 4.5.1;
.net源码网址:https://referencesource.microsoft.com/
注:本人水平有限,如果有错误,欢迎指正……