C#中 类 System.Collections.Generic.LinkedList<T> 代表双向链表,默认并没有定义单向链表。当然:双向链表可以实现单向链表的所有功能。
双向链表LinkedList<T>的C#源代码地址:
单向链表SingleLinkedList 如图:
单向循环链表CircularSingleLinkedList
双向链表DoubleLinkedList
双向循环链表CircularDoubleLinkedList
新建控制台应用程序LinkedListDemo:
新建节点类SingleLinkedNode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinkedListDemo
{
/// <summary>
/// 表示单向链表的一个节点
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingleLinkedNode<T>
{
/// <summary>
/// 初始化一个节点
/// </summary>
public SingleLinkedNode()
{
this.Next = null;
}
/// <summary>
/// 初始化一个节点,使用指定的节点值
/// </summary>
/// <param name="value"></param>
public SingleLinkedNode(T value)
{
this.Value = value;
}
/// <summary>
/// 当前节点对应的值
/// </summary>
public T Value { get; set; }
/// <summary>
/// 当前节点的下一个节点
/// </summary>
public SingleLinkedNode<T> Next { get; set; }
/// <summary>
/// 显示节点和以后节点
/// </summary>
public void Show()
{
SingleLinkedNode<T> node = this;
while (node != null)
{
Console.Write(node.Value);
node = node.Next;
if (node != null)
{
Console.Write("--->");
}
}
Console.WriteLine();
}
}
}
新建单向链表类SingleLinkedList
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinkedListDemo
{
/// <summary>
/// 单向链表,为了方便遍历,实现IEnumerable(可枚举)接口。
/// 同时方便排序,因此T限制为必须是实现IComparable(可比较)接口。
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingleLinkedList<T> : IEnumerable<T> where T : IComparable
{
/// <summary>
/// 初始化一个空的单向链表
/// </summary>
public SingleLinkedList()
{
this.Head = new SingleLinkedNode<T>();
}
/// <summary>
/// 使用一个节点来初始化单向链表
/// </summary>
/// <param name="next"></param>
public SingleLinkedList(SingleLinkedNode<T> next) : this()
{
this.Head.Next = next;
}
/// <summary>
/// 使用连续数据来初始化单向链表
/// </summary>
/// <param name="itemArray"></param>
public SingleLinkedList(T[] itemArray) : this()
{
SingleLinkedNode<T> current = Head;
SingleLinkedNode<T> next;
for (int i = 0; i < itemArray.Length; i++)
{
next = new SingleLinkedNode<T>(itemArray[i]);
//当前节点的下一个节点为新的节点
current.Next = next;
//指针偏移到新节点
current = next;
}
}
/// <summary>
/// 表示单向链表的头节点
/// </summary>
public SingleLinkedNode<T> Head { get; set; }
/// <summary>
/// 获取链表的长度:节点个数
/// </summary>
public int Count
{
get
{
int n = 0;
SingleLinkedNode<T> node = Head.Next;
while (node != null)
{
n++;
node = node.Next;
}
return n;
}
}
/// <summary>
/// 获取链表是否为空
/// </summary>
public bool IsEmpty
{
get
{
return Head.Next == null;
}
}
/// <summary>
/// 索引器:获得或者设置指定索引处的链表元素
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T this[int index]
{
get
{
if (index < 0 || index > Count)
{
throw new IndexOutOfRangeException("索引越界异常");
}
int n = 0;
SingleLinkedNode<T> node = Head.Next;
while (node != null)
{
if (index == n)
{
break;
}
node = node.Next;
n++;
}
if (node == null)
{
throw new IndexOutOfRangeException("已经找到链表的尾部,仍未找到该索引对应的元素");
}
return node.Value;
}
set
{
if (index < 0 || index > Count)
{
throw new IndexOutOfRangeException("索引越界异常");
}
int n = 0;
SingleLinkedNode<T> node = Head.Next;
while (node != null)
{
if (index == n)
{
break;
}
node = node.Next;
n++;
}
if (node == null)
{
throw new IndexOutOfRangeException("已经找到链表的尾部,仍未找到该索引对应的元素");
}
node.Value = value;
}
}
/// <summary>
/// 将单向链表转化为一个T类型的数组
/// </summary>
/// <returns></returns>
public T[] ToArray()
{
T[] array = new T[Count];
int n = 0;
SingleLinkedNode<T> node = Head.Next;
while (node != null)
{
array[n] = node.Value;
n++;
node = node.Next;
}
return array;
}
#region 插入或删除单向链表的节点
/// <summary>
/// 在链表的尾部增加一个元素
/// </summary>
/// <param name="value"></param>
public void Add(T value)
{
SingleLinkedNode<T> node = Head;
//如果链表的下一个节点为null,则循环终止
while (node != null && node.Next != null)
{
node = node.Next;
}
SingleLinkedNode<T> insertNode = new SingleLinkedNode<T>(value);
node.Next = insertNode;
}
/// <summary>
/// 在指定的索引处添加一个链表节点
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
public void Insert(int index, T value)
{
if (index < 0 || index > Count)
{
throw new ArgumentOutOfRangeException("索引越界异常");
}
int n = 0;
SingleLinkedNode<T> node = Head;
while (node != null)
{
if (index == n)
{
break;
}
n++;
node = node.Next;
}
//需要插入的节点
SingleLinkedNode<T> insertNode = new SingleLinkedNode<T>(value);
insertNode.Next = node.Next;//需要插入的节点的下一个节点是 【指定索引处的原节点的下一个节点】
node.Next = insertNode;//原节点的下一个节点 就是 当前插入的节点
}
/// <summary>
/// 在指定的索引处添加一个链表节点集合
/// </summary>
/// <param name="index"></param>
/// <param name="itemArray"></param>
public void InsertRange(int index, T[] itemArray)
{
if (index < 0 || index > Count)
{
throw new ArgumentOutOfRangeException("索引越界异常");
}
int n = 0;
SingleLinkedNode<T> node = Head;
while (node != null)
{
if (index == n)
{
break;
}
n++;
node = node.Next;
}
//记录找到索引处的节点的下一个节点
SingleLinkedNode<T> tempNode = node.Next;
//需要插入的节点
SingleLinkedNode<T> insertNode = null;
for (int i = 0; i < itemArray.Length; i++)
{
insertNode = new SingleLinkedNode<T>(itemArray[i]);
//当前节点的下一个节点为新的节点
node.Next = insertNode;
//指针偏移到新节点
node = insertNode;
}
node.Next = tempNode;//需要插入的节点的下一个节点是 【指定索引处的原节点的下一个节点】
}
/// <summary>
/// 移除指定值的第一个节点
/// </summary>
/// <param name="value"></param>
public void Remove(T value)
{
//是否已查找到指定值的节点
bool findNodeResult = false;
int n = 0;
SingleLinkedNode<T> node = Head;
SingleLinkedNode<T> frontNode = null;
while (node != null)
{
if (value.CompareTo(node.Value) == 0)
{
findNodeResult = true;
break;
}
n++;
frontNode = node;//记录指定值的上一个节点
node = node.Next;
}
if (!findNodeResult)
{
//如果没有找到指定值的节点,则什么也不做
return;
}
//如果上一个节点为null,说明是移除头节点,指定第二个节点作为头节点
if (frontNode == null)
{
Head = node.Next;
}
else //如果上一个节点不为null,则上一个节点的下一个直接指定为【指定值的节点的下一个节点】
{
frontNode.Next = node.Next;
}
}
/// <summary>
/// 移除指定索引的项
/// </summary>
/// <param name="index"></param>
public void RemoveAt(int index)
{
if (index < 0 || index >= Count)
{
throw new ArgumentOutOfRangeException("索引越界异常");
}
int n = 0;
SingleLinkedNode<T> node = Head.Next;
SingleLinkedNode<T> frontNode = null;
while (node != null)
{
if (n == index)
{
break;
}
n++;
frontNode = node;//记录指定值的上一个节点
node = node.Next;
}
//如果上一个节点为null,说明是移除头节点,指定第二个节点作为头节点
if (frontNode == null)
{
Head = node.Next;
}
else
{
frontNode.Next = node.Next;
}
}
#endregion
/// <summary>
/// 反转链表
/// </summary>
public SingleLinkedList<T> Reverse()
{
T[] itemArray = ToArray();
Array.Reverse(itemArray);
return new SingleLinkedList<T>(itemArray);
}
/// <summary>
/// 链表按照节点的值从小到大重新排序
/// </summary>
public SingleLinkedList<T> Sort()
{
//转化成数组重新排序
T[] itemArray = ToArray();
Array.Sort(itemArray);
//this.Head = new SingleLinkedNode<T>();
//SingleLinkedNode<T> current = Head;
//SingleLinkedNode<T> next;
//for (int i = 0; i < itemArray.Length; i++)
//{
// next = new SingleLinkedNode<T>(itemArray[i]);
// //当前节点的下一个节点为新的节点
// current.Next = next;
// //指针偏移到新节点
// current = next;
//}
//重新实例化
return new SingleLinkedList<T>(itemArray);
}
#region 实现IEnumerable接口,用于迭代Foreach
/// <summary>
/// 可以对接口进行Foreach遍历,迭代
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
SingleLinkedNode<T> node = Head.Next;
while (node != null)
{
yield return node.Value;
node = node.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
测试单项链表:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinkedListDemo
{
class Program
{
static void Main(string[] args)
{
SingleLinkedList<int> linkedList = new SingleLinkedList<int>(new int[] { 1, 2, 3 });
Console.WriteLine(string.Join("-->", linkedList));
linkedList.Add(5);
Console.WriteLine(string.Join("-->", linkedList));
linkedList.Insert(3, 4);
Console.WriteLine(string.Join("-->", linkedList));
linkedList.RemoveAt(2);
Console.WriteLine(string.Join("-->", linkedList));
linkedList.Add(3);
Console.WriteLine(string.Join("-->", linkedList));
linkedList = linkedList.Reverse();
Console.WriteLine(string.Join("-->", linkedList));
linkedList = linkedList.Sort();
Console.WriteLine(string.Join("-->", linkedList));
Console.ReadLine();
}
}
}