关于某道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 { getset; }
16         /// <summary>
17         /// 下一个节点
18         /// </summary>
19         public DoubleLinkNode<T> Next { getset; }
20         /// <summary>
21         /// 前一个节点
22         /// </summary>
23         public DoubleLinkNode<T> Previous { getset; }
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 { getprivate set; }
        
/// <summary>
        
/// 尾节点
        
/// </summary>
        public DoubleLinkNode<T> Last { getprivate set; }
        
/// <summary>
        
/// 节点数
        
/// </summary>
        public int Count { getprivate 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 == nullreturn;
            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 { getset; }
    }

下面是结果
posted @ 2009-09-08 21:06  Farmer  阅读(3597)  评论(3编辑  收藏  举报