C# 判断单链表是否有环
基本思路:设置两个指针,一快(fast)一慢(slow),向链表末端移动,若fast=slow,有环,若fast=null,无环。
/// <summary> /// 单链表结点类 /// </summary> /// <typeparam name="T"></typeparam> public class SNode<T> { private T data; //数据域 private SNode<T> next; //应用域 public SNode(T val, SNode<T> p) { data = val; next = p; } public SNode(SNode<T> p) { next = p; } public SNode(T val) { data = val; next = null; } public SNode() { data = default(T); next = null; } //数据域属性 public T Data { get { return data; } set { data = value; } } //引用域属性 public SNode<T> Next { get { return next; } set { next = value; } } }
/// <summary> /// 单链表结点类 /// </summary> /// <typeparam name="T"></typeparam> public class SNode<T> { private T data; //数据域 private SNode<T> next; //应用域 public SNode(T val, SNode<T> p) { data = val; next = p; } public SNode(SNode<T> p) { next = p; } public SNode(T val) { data = val; next = null; } public SNode() { data = default(T); next = null; } //数据域属性 public T Data { get { return data; } set { data = value; } } //引用域属性 public SNode<T> Next { get { return next; } set { next = value; } } }
/// <summary> /// 单链表 /// </summary> /// <typeparam name="T"></typeparam> class SLinkList<T> { public SNode<T> start; //单链表的头引用 public int length; //单链表的长度 public SLinkList() { start = null; } //在单链表末尾追加数据元素 public void InsertNode(SNode<T> a) { if (start == null) { start = new SNode<T>(a); return; } SNode<T> current = start;//使current指向第一个结点 while (current.Next != null) { //找到链表中最后一个结点(从start一直扫描到最后(即next=null)) current = current.Next; } //使current的next字段指向新结点 current.Next = new SNode<T>(a); length++; } //在单链表的第i个数据元素的位置前插入一个数据元素 public void InsertNode(SNode<T> val, int i) { SNode<T> current; SNode<T> previous; if (i < 1) { Console.WriteLine("Postion is Error !"); return; } SNode<T> newnode = new SNode<T>(val); //在空链表或第一个元素前插入第一个元素 if (i == 1) { newnode.Next = start; start = newnode; length++; return; } //单链表的两个元素间插入一个元素 //使current指向第一个结点 current = start; previous = null; int j = 1; while (current != null && j < i) { //使previous指向curent previous = current; //使current指向序列中的下一个结点 current = current.Next; j++; } if (j == i) { previous.Next = newnode; newnode.Next = current; length++; } } public int GetLength() { return length; } public void Clear() { //单链表清空后,原结点占有的空间不会一直保留 由垃圾回收器回收 start = null; } public bool IsEmpty() { if (start == null) { return true; } else { return false; } } //删除单链表的第i个元素 public void DeleteNode(int i) { if (IsEmpty() || i < 1) { Console.WriteLine("Link is Empty or Positon is Error !"); return; } SNode<T> current = start; if (i == 1) { start = current.Next;//使用current指向单链表中的下一个结点 length--; return; } SNode<T> previous = null; int j = 1; while (current.Next != null && j < i) { previous = current; current = current.Next; j++; } if (j == i) { previous.Next = current.Next; current = null; length--; } else { Console.WriteLine("The {0}th node is no exsit !", i); } } //获得单链表的第i个数据元素 public SNode<T> SearchNode(int i) { if (IsEmpty()) { Console.WriteLine("Link is Empty !"); return null; } SNode<T> current = start; int j = 1; while (current.Next != null && j < i) { current = current.Next;//使current指向序列中的下一个结点 直到i j++; } if (j == i) { return current; } else { Console.WriteLine("The {0}th node is no exsit !", i); return null; } } //在单链表中查找值为value的数据 public SNode<T> SearchNode(SNode<T> value) { if (IsEmpty()) { Console.WriteLine("List is Empty !"); return null; } SNode<T> current = start; int i = 0; while (!current.Data.ToString().Contains(value.ToString()) && current != null) { current = current.Next; i++; } if (current != null) { return current; } else { return null; } } }
class Program { /// <summary> /// 判断单链表是否有环 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="link"></param> /// <returns></returns> static int isCricle<T>(SLinkList<T> link) { SNode<T> fast = link.start; SNode<T> slow = link.start; while (link.start.Next != null) { slow = slow.Next; fast = fast.Next; if (fast != null && fast.Next != null) fast = fast.Next; else return 0; link.start = link.start.Next; if (fast == slow) return 1; } return 0; } static void Main(string[] args) { SLinkList<int> link = new SLinkList<int>(); SNode<int> node = new SNode<int>(1); link.InsertNode(node, 1); link.InsertNode(node, 2); link.InsertNode(node, 3); SNode<int> c = link.SearchNode(3); link.InsertNode(node, 4); link.InsertNode(node, 5); while (link.start.Next != null) link.start = link.start.Next; link.start.Next = c; Console.WriteLine(isCricle<int>(link)); Console.ReadLine(); } }
返回1,有环。
浙公网安备 33010602011771号