本文继续
《关于某道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 }
这里使用的是泛型类,他的优势就不讨论了,下面是循环链表类
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>[] 来存储数据,所以索引的处理显得非常的麻烦(如果用了数组就存在链表的容量问题),希望高手们能给出好的方法。
/// 双向循环链表
/// </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;
}
}
下面就是具体实现了
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 ; }
}
{
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 ; }
}
下面是结果