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,有环。

posted on 2015-03-21 09:14  YuanSong  阅读(516)  评论(0)    收藏  举报

导航