封装一个集合:
1.提供push(T value)在尾部添加新元素,
2.pop()删除并返回最后一个元素,
3.shift()删除并返回第一个元素,
4.unshift(T value)在首位添加新元素;
5.底层可以用数组,list或者链表模式保存数据
下面有两种实现方案:
(1)顺序结构:难点是数组循环存储
(2)链表:更简单一点
顺序结构(数组)实现:
using System;
using System.Collections;
using System.Collections.Generic;
namespace cchoop
{
class Program
{
static void Main(string[] args)
{
MyCollection<int> collection = new MyCollection<int>();
collection.Push(1);
collection.Push(2);
collection.Push(3);
collection.Push(4);
collection.Push(5);
collection.Push(6);
PrintCollection(collection);
Console.WriteLine("Pop:" + collection.Pop());
Console.WriteLine("UnShift:" + collection.Shift());
Console.WriteLine("UnShift:" + collection.Shift());
PrintCollection(collection);
collection.UnShift(6);
collection.UnShift(7);
collection.UnShift(8);
collection.UnShift(9);
collection.UnShift(9);
PrintCollection(collection);
Console.WriteLine("集合的长度:" + collection.Count);
}
static void PrintCollection(IEnumerable collection)
{
foreach (var item in collection)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
class MyCollection<T> : IEnumerable<T>
{
private T[] arr;
private int head; //头
private int tail; //尾
private int capacity;
public int Count { get; private set; }
public MyCollection()
: this(4)
{
}
public MyCollection(int capacity)
{
this.capacity = capacity;
this.head = -1;
this.tail = -1;
this.Count = 0;
this.arr = new T[capacity];
}
//删除并返回最后一个元素
public T Pop()
{
//如果集合为空,抛出异常
if (this.Count <= 0)
{
throw new Exception("异常:集合为空");
}
T popData = arr[tail];
arr[tail] = default(T);
tail = (tail + this.capacity - 1) % this.capacity;
this.Count--;
return popData;
}
//删除并返回第一个元素
public T Shift()
{
//如果集合为空,抛出异常
if (this.Count <= 0)
{
throw new Exception("异常:集合为空!");
}
T shiftData = arr[head];
arr[head] = default(T);
head = (head + 1) % this.capacity;
this.Count--;
return shiftData;
}
//在尾部添加新元素
public void Push(T value)
{
//扩充容量
if (Count == this.capacity)
{
ExpandCapacity();
}
tail = (tail + 1) % this.capacity;
if (this.Count == 0)
{
head = tail;
}
arr[tail] = value;
this.Count++;
}
//在首位添加新元素
public void UnShift(T value)
{
//扩充容量
if (Count == this.capacity)
{
ExpandCapacity();
}
head = (head + this.capacity - 1) % this.capacity;
if (this.Count == 0)
{
tail = head;
}
arr[head] = value;
this.Count++;
}
private void ExpandCapacity()
{
this.capacity *= 2;
T[] newArr = new T[this.capacity];
if (head < tail)
{
Array.Copy(arr, head, newArr, 0, this.Count);
}
else //当尾在头前面时
{
Array.Copy(arr, head, newArr, 0, this.Count - head);
Array.Copy(arr, 0, newArr, this.Count - head, this.tail + 1);
}
this.head = 0;
this.tail = this.Count - 1;
this.arr = newArr;
}
public IEnumerator<T> GetEnumerator()
{
return new MyEnumeator<T>(this.arr, this.head, this.tail, this.Count);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new MyEnumeator<T>(this.arr, this.head, this.tail, this.Count);
}
class MyEnumeator<T> : IEnumerator<T>
{
private T[] _arr;
private int index;
private int _head;
private int _tail;
private int _count;
public MyEnumeator(T[] arr, int head, int tail, int count)
{
this._arr = arr;
this._head = head;
this._tail = tail;
this.index = _head - 1;
this._count = count;
}
public T Current
{
get
{
return _arr[index];
}
}
public void Dispose()
{
Console.WriteLine();
}
object IEnumerator.Current
{
get
{
return _arr[index];
}
}
public bool MoveNext()
{
if (this._count == 0)
{
return false;
}
index = (index + 1) % _arr.Length;
_count--;
return true;
}
public void Reset()
{
this.index = _head - 1;
}
}
}
}
}
链表实现:
using System;
using System.Collections;
using System.Collections.Generic;
namespace cchoop
{
class Program
{
static void Main(string[] args)
{
MyLinkedCollection<int> collection = new MyLinkedCollection<int>();
collection.Push(3);
collection.Push(4);
collection.Push(5);
collection.UnShift(6);
collection.UnShift(7);
PrintCollection(collection);
Console.WriteLine("Pop:" + collection.Pop());
Console.WriteLine("Shift:" + collection.Shift());
}
static void PrintCollection(IEnumerable collection)
{
foreach (var item in collection)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
}
class MyLinkedCollectionNode<T>
{
public T Value { get; private set; }
public MyLinkedCollectionNode<T> Next;
public MyLinkedCollectionNode<T> Previous;
public MyLinkedCollectionNode(MyLinkedCollectionNode<T> previous, T value, MyLinkedCollectionNode<T> next)
{
this.Previous = previous;
this.Value = value;
this.Next = next;
}
}
class MyLinkedCollection<T> : IEnumerable<T>
{
private MyLinkedCollectionNode<T> Head;
private MyLinkedCollectionNode<T> Tail;
public int Count { get; private set; }
public MyLinkedCollection()
{
Head = null;
}
//删除并返回最后一个元素
public T Pop()
{
if (this.Count == 0)
{
throw new Exception("异常:集合为空!");
}
T value = Tail.Value;
Tail = Tail.Previous;
Tail.Next = null;
this.Count--;
return value;
}
//删除并返回第一个元素
public T Shift()
{
if (this.Count == 0)
{
throw new Exception("异常:集合为空!");
}
T value = Head.Value;
Head = Head.Next;
Head.Previous = null;
this.Count--;
return value;
}
//在尾部添加新元素
public void Push(T value)
{
MyLinkedCollectionNode<T> newNode = new MyLinkedCollectionNode<T>(Tail, value, null);
if (Tail != null)
{
Tail.Next = newNode;
}
else
{
Head = newNode;
}
Tail = newNode;
this.Count++;
}
//在首位添加新元素
public void UnShift(T value)
{
MyLinkedCollectionNode<T> newNode = new MyLinkedCollectionNode<T>(null, value, Head);
if (Head != null)
{
Head.Previous = newNode;
}
else
{
Tail = newNode;
}
Head = newNode;
this.Count++;
}
public IEnumerator<T> GetEnumerator()
{
return new MyEnumerator<T>(this.Head);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new MyEnumerator<T>(this.Head);
}
class MyEnumerator<T> : IEnumerator<T>
{
private MyLinkedCollectionNode<T> head;
private MyLinkedCollectionNode<T> current;
public MyEnumerator(MyLinkedCollectionNode<T> head)
{
this.head = head;
this.current = null;
}
public T Current
{
get { return current.Value; }
}
public void Dispose()
{
Console.WriteLine();
}
object IEnumerator.Current
{
get { return current.Value; }
}
public bool MoveNext()
{
if (current == null)
{
current = head;
}
else
{
current = current.Next;
}
if (current == null)
{
return false;
}
return true;
}
public void Reset()
{
current = null;
}
}
}
}