程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#上機題 - 雙向循環鏈表

C#上機題 - 雙向循環鏈表

編輯:關於C#

本文繼續《C#上機題的OO - 策略模式》中的題目,但這是使用的是雙向循環鏈表。當第一次看到這題我首先想到的是循環鏈表,但題目要求面向對象的方法,汗~

首先是雙向鏈表的節點類

1 /// <summary>
2  /// 雙向鏈表節點
3  /// </summary>
4  /// <typeparam name="T"></typeparam>
5  public class DoubleLinkNode<T>
6  {
7   public DoubleLinkNode() { }
8   public DoubleLinkNode(T item)
9   {
10    Value = item;
11   }
12   /// <summary>
13   /// 節點值
14   /// </summary>
15   public T Value { get; set; }
16   /// <summary>
17   /// 下一個節點
18   /// </summary>
19   public DoubleLinkNode<T> Next { get; set; }
20   /// <summary>
21   /// 前一個節點
22   /// </summary>
23   public DoubleLinkNode<T> Previous { get; set; }
24   public override string ToString()
25   {
26    return Value.ToString();
27   }
28 }

這裡使用的是泛型類,他的優勢就不討論了,下面是循環鏈表類

/// <summary>
    /// 雙向循環鏈表
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CircleList<T> : IEnumerable<T>
    {
        private int currentIndex;
        private DoubleLinkNode<T> current;
        /// <summary>
        /// 頭節點
        /// </summary>
        public DoubleLinkNode<T> First { get; private set; }
        /// <summary>
        /// 尾節點
        /// </summary>
        public DoubleLinkNode<T> Last { get; private set; }
        /// <summary>
        /// 節點數
        /// </summary>
        public int Count { get; private set; }
        /// <summary>
        /// 索引
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public DoubleLinkNode<T> this[int index]
        {
            get
            {
                if (Count - index < index)
                {
                    currentIndex = Count - 1;
                    current = Last;
                    while (currentIndex > 0)
                    {
                        if (currentIndex == index) break;
                        currentIndex--;
                        current = current.Previous;
                    }
                }
                else
                {
                    Reset();
                    while (currentIndex < Count - 1)
                    {
                        if (currentIndex == index) break;
                        currentIndex++;
                        current = current.Next;
                    }
                }
                return current;
            }
        }
        /// <summary>
        /// 在尾部添加節點
        /// </summary>
        /// <param name="node"></param>
        public void AddLast(DoubleLinkNode<T> node)
        {
            if (Last == null) Last = node;
            if (First == null) First = node;
            Last.Next = node;
            node.Previous = Last;
            Last = node;
            node.Next = First;
            First.Previous = node;
            Count++;
            Last.Next = First;
        }
        /// <summary>
        /// 在尾部添加節點
        /// </summary>
        /// <param name="item"></param>
        public void AddLast(T item)
        {
            DoubleLinkNode<T> node = new DoubleLinkNode<T>(item);
            AddLast(node);
        }
        /// <summary>
        /// 移除節點
        /// </summary>
        /// <param name="node"></param>
        public void Remove(DoubleLinkNode<T> node)
        {
            node.Previous.Next = node.Next;
            node.Next.Previous = node.Previous;
            Count--;
        }
        /// <summary>
        /// 移除節點
        /// </summary>
        /// <param name="item"></param>
        public void Remove(T item)
        {
            DoubleLinkNode<T> node = Find(o => o.Value.Equals(item));
            if (node == null) return;
            Remove(node);
            Count--;
        }
        /// <summary>
        /// 查找節點
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        public DoubleLinkNode<T> Find(Predicate<DoubleLinkNode<T>> match)
        {
            Reset();
            while (currentIndex < Count)
            {
                if (match(current))
                {
                    return current;
                }
                currentIndex++;
                current = current.Next;
            }
            return null;
        }
        public IEnumerator<T> GetEnumerator()
        {
            Reset();
            while (currentIndex < Count)
            {
                yield return current.Value;
                current = current.Next;
                currentIndex++;
            }
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
        public override string ToString()
        {
            string s = string.Empty;
            Reset();
            while (currentIndex < Count)
            {
                s += string.Format("Node:{0}   NextNode:{1}   PreviousNode:{2}\r\n", current, current.Next, current.Previous);
                currentIndex++;
                current = current.Next;
            }
            return s;
        }
        /// <summary>
        /// 清除
        /// </summary>
        public void Clear()
        {
            Count = 0;
            First = null;
            Last = null;
        }
        private void Reset()
        {
            currentIndex = 0;
            current = First;
        }
    }

由於沒用使用DoubleLinkNode<T>[] 來存儲數據,所以索引的處理顯得非常的麻煩(如果用了數組就存在鏈表的容量問題),希望高手們能給出好的方法。

下面就是具體實現了

class Program
{
 static void Main(string[] args)
 {
  //初始化數據
  CircleList<Person> list = new CircleList<Person>();
  for (int i = 0; i < 17; i++)
  {
   list.AddLast(new Person(i + 1));
  }
  //當前報數人
  DoubleLinkNode<Person> current = list.First;
  //報數序號
  int k = 0;
  //循環報數
  while (list.Count > 1)
  {
   k++;
   Console.WriteLine(string.Format("{0}:{1}", current.Value.Id, k));
   if (k % 3 == 0)
    list.Remove(current);
   current = current.Next;
  }
  Console.WriteLine(string.Format("Last Person:{0}", current.Value.Id));
  Console.Read();
 }
}
/// <summary>
/// 玩家
/// </summary>
public class Person
{
 public Person(int id)
 {
  this.Id = id;
 }
 public int Id { get; set; }
}

下面是結果

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved