和单链表差不多,只不过添加一个尾指针,指向最后一个元素,头节点就不用公开了,默认一个私有字段即可,可以快速获取最后一个元素和第一个元素,时间复杂度为O(1)。
节点类
/// <summary>
/// 节点
/// </summary>
public class Node<T>
{
private T data;
private Node<T> next;
public T Data
{
get
{
return data;
}
set
{
data = value;
}
}
public Node<T> Next
{
get
{
return next;
}
set
{
next = value;
}
}
public Node()
{
data = default;
next = null;
}
public Node(T data, Node<T> next)
{
this.data = data;
this.next = next;
}
public Node(T data)
{
this.data = data;
this.next = null;
}
public Node(Node<T> next)
{
this.next = next;
}
}
QCircularLinkedList:
添加了Count属性
public class QCircularLinkedList<T>
{
/// <summary>
/// 头结点
/// </summary>
private Node<T> head;
/// <summary>
/// 尾结点
/// </summary>
private Node<T> rear;
/// <summary>
/// 只暴露一个尾结点属性即可
/// </summary>
public Node<T> Rear
{
get { return rear; }
set { rear = value; }
}
public QCircularLinkedList()
{
head = null;
rear = head;
}
public QCircularLinkedList(T head = default)
{
this.head = new Node<T>(head);
this.head.Next = this.head;
this.rear = this.head;
}
private int count;
public int Count
{
get { return count; }
set { count = value; }
}
public bool IsEmpty()
{
return head == null || head.Next == head;
}
public void Clear()
{
head.Next = head;
rear = head;
count = 0;
}
/// <summary>
/// 在末尾添加数据
/// </summary>
/// <param name="data"></param>
public void Append(T data)
{
if (head == null)
{
head = new Node<T>();
head.Next = head;
rear = head;
}
Node<T> p = head;
while (p.Next != head)
{
p = p.Next;
}
var node = new Node<T>(data);
p.Next = node;
node.Next = head;
rear = node;
count++;
}
/// <summary>
/// 插入索引元素前面,所以不会插到最后,不用更新rear
/// </summary>
/// <param name="index"></param>
/// <param name="data"></param>
public void Insert(int index, T data)
{
if (index < 1 || IsEmpty())
{
//throw new System.Exception("插入位置不允许或链表为空!");
return;
}
Node<T> p = head;
int i = 1;
while (p.Next != head && i < index)
{
p = p.Next;
++i;
}
if (p.Next == head || i > index)
{
//throw new System.Exception("插入位置不正确!");
return;
}
Node<T> node = new(data);
node.Next = p.Next;
p.Next = node;
count++;
}
public T GetItem(int index)
{
if (index < 1 || IsEmpty())
{
//throw new System.Exception("获取位置不允许或链表为空!");
return default;
}
Node<T> p = head.Next;
int i = 1;
while (p != head && i < index)
{
p = p.Next;
++i;
}
if (p == head || i > index)
{
//throw new System.Exception("未找到元素!");
return default;
}
return p.Data;
}
public void Delete(int index)
{
if (index < 1 || IsEmpty())
{
//throw new System.Exception("删除位置不允许或链表为空!");
return;
}
Node<T> p = head;
int i = 1;
while (p.Next != head && i < index)
{
p = p.Next;
++i;
}
if (p == head || i > index)
{
//throw new System.Exception("未找到元素!");
return;
}
p.Next = p.Next.Next;
//如果删除的是最后一个元素,更新rear
if (p.Next == head)
{
rear = p;
}
count--;
}
/// <summary>
/// 整表创建:头插
/// </summary>
/// <param name="n"></param>
public void CreatListHead(int n, T data = default)
{
head = new Node<T>();
head.Next = head;
rear = head;
int i = 1;
Node<T> p = default;
while (i <= n)
{
p = new Node<T>(data);
p.Next = head.Next;
head.Next = p;
}
rear = p;
count = n;
}
/// <summary>
/// 整表创建:尾插
/// </summary>
/// <param name="n"></param>
public void CreatListEnd(int n, T data = default)
{
head = new Node<T>();
head.Next = head;
rear = head;
Node<T> p = head;
int i = 1;
while (i <= n)
{
p.Next = new Node<T>(data);
p = p.Next;
}
p.Next = head;
rear = p;
count = n;
}
}