单循环链表
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace DataStruct.List
{
/// <summary>
/// 循环链表
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
class CycleLinkList<T> : IList<T>, IEnumerable<T>
where T : IComparable<T>
{
/// <summary>
/// 获取头结点
/// </summary>
public Node<T> Head { get; }
/// <summary>
/// 获取尾节点
/// </summary>
public Node<T> P { get; private set; }
/// <summary>
/// 节点数量
/// </summary>
private int count;
/// <summary>
/// 构造器
/// </summary>
public CycleLinkList()
{
this.Head = new Node<T>();
this.Head.Next = this.Head;
this.P = this.Head;
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="array">数组</param>
public CycleLinkList(params T[] array)
{
Node<T> p = this.Head = new Node<T>();
foreach (var item in array)
{
Node<T> t = new Node<T>(item);
p.Next = t;
p = p.Next;
this.count++;
}
p.Next = Head;
this.P = p;
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="array">数组</param>
/// <param name="reverse">是否使用尾插法</param>
public CycleLinkList(IEnumerable<T> array, bool reverse = false)
{
if (reverse)
{
this.Head = new Node<T>();
bool flag=true;
Node<T> t = null;
foreach (var item in array)
{
if(flag)
{
t = new Node<T>(item, Head);
flag = false;
this.P = t;
}
else
t = new Node<T>(item, Head.Next);
Head.Next = t;
this.count++;
}
}
else
{
Node<T> p = this.Head = new Node<T>();
foreach (var item in array)
{
Node<T> t = new Node<T>(item);
p.Next = t;
p = p.Next;
this.count++;
}
p.Next = Head;
this.P = p;
}
}
/// <summary>
/// 检查索引
/// </summary>
/// <param name="index">索引</param>
private void RaiseForIndex(ref int index)
{
if (index < 0)
index += this.count;
if (index < 0 || index >= count)
throw new IndexOutOfRangeException("列表索引访问越界了");
}
/// <summary>
/// 检查区间
/// </summary>
/// <param name="index">索引</param>
private void RaiseForRange(ref int start, ref int end)
{
if (start < 0) start += count;
if (end < 0) end += count;
var cnt = end - start;
if (start < 0 || end < 0 || cnt <= 0 || start >= count || end > count)
throw new IndexOutOfRangeException("列表索引访问越界了");
}
/// <summary>
/// 查找给定索引元素的前驱节点
/// </summary>
/// <param name="index">索引</param>
/// <returns>返回节点</returns>
public Node<T> FindPrevious(int index)
{
RaiseForIndex(ref index);
int i = 0;
Node<T> p = this.Head;
while (i < index && p.Next != this.Head)
{
p = p.Next;
i++;
}
return p;
}
///// <summary>
///// 返回倒数第index个元素的节点
///// </summary>
///// <param name="index">倒数第几</param>
///// <returns>返回该节点</returns>
//public Node<T> FindLast(int index)
//{
// if(index<=0)
// throw new IndexOutOfRangeException("索引访问越界");
// Node<T> p= this.Head;
// for (int i = 0; i < index; i++)
// {
// if (p.Next == null)
// throw new IndexOutOfRangeException("索引访问越界");
// p = p.Next;
// }
// Node<T> q = this.Head;
// while(p.Next!=null)
// {
// p = p.Next;
// q = q.Next;
// }
// return q.Next;
//}
/// <summary>
/// 索引器
/// </summary>
/// <param name="index">索引值</param>
/// <returns>返回对应数据</returns>
public T this[int index]
{
get
{
return FindPrevious(index).Next.Data;
}
set
{
FindPrevious(index).Next.Data = value;
}
}
/// <summary>
/// 节点数量
/// </summary>
public int Count => this.count;
/// <summary>
/// 增加元素
/// </summary>
/// <param name="val">元素变量</param>
public void Add(T val)
{
Node<T> t = new Node<T>(val, this.Head);
this.P.Next = t;
this.P =t;
this.count++;
}
/// <summary>
/// 清理
/// </summary>
public void Clear()
{
this.Head.Next = Head;
this.count = 0;
}
/// <summary>
/// 查看数据在列表中的位置
/// </summary>
/// <param name="val">数据</param>
/// <returns>返回索引</returns>
public int? IndexOf(T val)
{
int i = 0;
var p = this.Head;
while (i < this.count)
{
p = p.Next;
if (p.Data.CompareTo(val) == 0)
return i;
i++;
}
return null;
}
/// <summary>
/// 插入元素
/// </summary>
/// <param name="index">元素索引</param>
/// <param name="val">插入元素值</param>
public void Insert(int index, T val)
{
var p = this.FindPrevious(index);
Node<T> temp = new Node<T>(val, p.Next);
p.Next = temp;
this.count++;
}
/// <summary>
/// 判断列表是否包含某个元素
/// </summary>
/// <param name="val">元素</param>
/// <returns>返回是否包含</returns>
public bool IsContains(T val) => this.IndexOf(val) != null;
/// <summary>
/// 判空
/// </summary>
/// <returns>表是否为空</returns>
public bool IsEmpty() => this.Head.Next == this.Head;
/// <summary>
/// 删除元素
/// </summary>
/// <param name="index">元素索引</param>
/// <returns>返回要删除的元素</returns>
public T Remove(int index)
{
var p = this.FindPrevious(index);
var q = p.Next;
var temp = q.Data;
p.Next = q.Next;
this.count--;
//如果要删除的节点为尾巴节点:改变尾巴节点指向
if (p.Next == this.Head)
this.P = p;
return temp;
}
/// <summary>
/// 覆盖ToString方法
/// </summary>
/// <returns>返回字符串</returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("[");
Node<T> p = this.Head;
while (p.Next != this.Head)
{
p = p.Next;
sb.Append(p);
}
sb.Append("]");
return sb.ToString();
}
/// <summary>
/// 转化为数组
/// </summary>
/// <returns>数组</returns>
public T[] ToArray()
{
T[] array = new T[count];
int i = 0;
foreach (var item in this)
array[i++] = item;
return array;
}
/// <summary>
/// 隐式类型转换
/// </summary>
/// <param name="array">顺序表</param>
public static explicit operator CycleLinkList<T>(SequenceList<T> ls) => new CycleLinkList<T>(ls.ToArray());
/// <summary>
/// 显式类型转换
/// </summary>
/// <param name="array">数组</param>
public static implicit operator CycleLinkList<T>(T[] array) => new CycleLinkList<T>(array);
/// <summary>
/// 获取迭代器
/// </summary>
/// <returns>返回迭代器</returns>
public IEnumerator<T> GetEnumerator()
{
var p = this.Head;
while (p.Next != this.Head)
{
p = p.Next;
yield return p.Data;
}
}
/// <summary>
/// 获取迭代器
/// </summary>
/// <returns>返回迭代器</returns>
IEnumerator IEnumerable.GetEnumerator()
{
var p = this.Head;
while (p.Next != this.Head)
{
p = p.Next;
yield return p.Data;
}
}
/// <summary>
/// 范围添加
/// </summary>
/// <param name="collection">可迭代集合</param>
public void AddRange(IEnumerable<T> collection)
{
foreach (var item in collection)
{
this.P.Next = new Node<T>(item, this.Head);
P = P.Next;
this.count++;
}
}
/// <summary>
/// 范围移除
/// </summary>
/// <param name="start">开始索引</param>
/// <param name="end">结束索引</param>
public void RemoveRange(int start, int end)
{
RaiseForRange(ref start, ref end);
Node<T> pstart = this.FindPrevious(start);
Node<T> pend = this.FindPrevious(end - 1);
pstart.Next = pend.Next.Next;
//如果要删除的节点包含尾巴节点:改变尾巴节点指向
if (pstart.Next==this.Head)
this.P = pstart;
}
/// <summary>
/// 链表1复制到链表2
/// </summary>
/// <param name="t1">顺序表1</param>
/// <param name="t2">顺序表2</param>
/// <param name="start">开始索引</param>
/// <param name="end">结束索引</param>
public static bool TryCopy(CycleLinkList<T> t1, out CycleLinkList<T> t2, int start, int end)
{
if (start < 0) start += t1.count;
if (end < 0) end += t1.count;
var cnt = end - start;
if (start < 0 || end < 0 || cnt <= 0 || start >= t1.count || end > t1.count)
{
t2 = null;
return false;
}
t2 = new CycleLinkList<T>();
Node<T> q = t2.Head, p = t1.FindPrevious(start);
while (p.Next != t1.Head && start < end)
{
p = p.Next;
q.Next = new Node<T>(p.Data, null);
q = q.Next;
start++;
}
q.Next = t2.Head;
t2.P = q;
return true;
}
/// <summary>
/// 链表切片
/// </summary>
/// <param name="start">开始索引</param>
/// <param name="end">结束索引</param>
/// <returns>切片结果</returns>
public CycleLinkList<T> this[(int start, int end) t]
{
get
{
TryCopy(this, out CycleLinkList<T> ans, t.start, t.end);
return ans;
}
}
/// <summary>
/// 链表切片
/// </summary>
/// <param name="start">开始索引</param>
/// <param name="end">结束索引</param>
/// <param name="step">结束索引</param>
/// <returns>切片结果</returns>
public CycleLinkList<T> this[(int start, int end, int step) t]
{
get
{
if (t.step <= 0)
throw new IndexOutOfRangeException("列表索引访问越界了");
RaiseForRange(ref t.start, ref t.end);
var ls = new CycleLinkList<T>();
Node<T> q = ls.Head, p = this.FindPrevious(t.start);
int i = 0;
int cnt = 0;
while (p.Next != this.Head && i < t.end)
{
p = p.Next;
if (cnt == t.step || i == t.start)
{
q.Next = new Node<T>(p.Data, null);
q = q.Next;
cnt = 0;
}
i++;
cnt++;
}
q.Next = ls.Head;
ls.P = q;
return ls;
}
}
/// <summary>
/// 删除列表最后一个元素
/// </summary>
/// <returns>返回被删除的元素值</returns>
public T Pop()
{
Node<T> p = this.FindPrevious(this.count - 1);
Node<T> q = p.Next;
var temp = q.Data;
p.Next =q.Next;
this.P = p;
this.count--;
return temp;
}
/// <summary>
/// 逆置
/// </summary>
public void Reverse()
{
Node<T> p = this.Head.Next, q = null, t = null;
while (p != null)
{
t = p.Next;
p.Next = q;
q = p;
p = t;
}
}
}
循环链表解决约瑟夫问题
/// <summary>
/// 约瑟夫问题
/// </summary>
/// <param name="n">n个人</param>
/// <param name="m">杀掉第m个</param>
/// <returns>依次返回可枚举集合</returns>
public static IEnumerable<int> Josephus(int n, int m)
{
CycleLinkList<int> rec = new CycleLinkList<int>(Util.range(1, n));
Node<int> p = rec.Head.Next;
while (p.Next != p)
{
for (int i = 1; i < m - 1; ++i)
p = p.Next;
Node<int> q = p.Next;
yield return q.Data;
p.Next = q.Next;
p = p.Next;
}
yield return p.Data;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。