LinkedList集合:
- 数组和List、ArrayList集合都有一个重大的缺陷,就是从数组的中间位置删除或插入一个元素需要付出很大的代价,其原因是数组中处于被删除元素之后的所有元素都要向数组的前端移动。
- LinkedList(底层是由链表实现的)基于链表的数据结构,很好的解决了数组删除插入效率低的问题,且不用动态的扩充数组的长度。
- LinkedList的优点:插入、删除元素效率比较高;缺点:访问效率比较低。
MyLinkedList的实现:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace cchoop
{
class Program
{
static void Main(string[] args)
{
MyLinkedList<int> myList = new MyLinkedList<int>();
myList.Add(3);
myList.Add(4);
myList.Remove(3);
myList.Add(5);
myList.Add(6);
MyLinkedListNode<int> node = myList.AddFirst(13);
myList.AddBefore(node, 89);
myList.AddAfter(node, 189);
Console.WriteLine(myList.Count);
Console.WriteLine(myList.First.Value);
Console.WriteLine(myList.First.Next.Value);
Console.WriteLine(myList.Last.Value);
Console.WriteLine(myList.Last.Previous.Value);
foreach (var item in myList)
{
Console.Write(item + " ");
}
}
}
class MyLinkedListNode<T>
{
public T Value { get; set; }
public MyLinkedListNode<T> Previous { get; set; }
public MyLinkedListNode<T> Next { get; set; }
public MyLinkedList<T> List { get; private set; }
public MyLinkedListNode(MyLinkedList<T> list, MyLinkedListNode<T> previous, MyLinkedListNode<T> next, T value)
{
this.List = list;
this.Previous = previous;
this.Next = next;
this.Value = value;
}
}
class MyLinkedList<T> : ICollection<T>
{
public MyLinkedListNode<T> First { get; private set; }
public MyLinkedListNode<T> Last { get; private set; }
public int Count { get; private set; }
public MyLinkedList()
{
this.First = null;
this.Last = null;
this.Count = 0;
}
//未实现
private MyLinkedList(ICollection<T> collection)
{
}
/// <summary>
/// 添加到链表尾部
/// </summary>
/// <param name="item">添加的数据</param>
public void Add(T item)
{
this.AddLast(item);
}
public MyLinkedListNode<T> AddBefore(MyLinkedListNode<T> node, T item)
{
ThrowArgumentNullException(node);
if (IsEmpty)
{
Console.WriteLine("链表为空!插入失败");
return default(MyLinkedListNode<T>);
}
if (node.List != this)
{
return default(MyLinkedListNode<T>);
}
MyLinkedListNode<T> newNode = new MyLinkedListNode<T>(this, node.Previous, node, item);
if (node == this.First)
{
this.First = newNode;
node.Previous = newNode;
}
else
{
node.Previous.Next = newNode;
node.Previous = newNode;
}
this.Count++;
return newNode;
}
public MyLinkedListNode<T> AddAfter(MyLinkedListNode<T> node, T item)
{
ThrowArgumentNullException(node);
if (node.List != this)
{
return default(MyLinkedListNode<T>);
}
MyLinkedListNode<T> newNode = new MyLinkedListNode<T>(this, node, node.Next, item);
if (node == this.Last)
{
this.Last = newNode;
node.Next = newNode;
}
else
{
node.Next.Previous = newNode;
node.Next = newNode;
}
this.Count++;
return newNode;
}
public MyLinkedListNode<T> AddFirst(T item)
{
MyLinkedListNode<T> node = new MyLinkedListNode<T>(this, null, this.First, item);
if (this.First == null)
{
this.First = node;
this.Last = this.First;
}
else
{
node.Next = this.First;
this.First = node;
}
this.Count++;
return node;
}
public MyLinkedListNode<T> AddLast(T item)
{
MyLinkedListNode<T> node = new MyLinkedListNode<T>(this, this.Last, null, item);
if (this.Last == null)
{
this.Last = node;
this.First = this.Last;
}
else
{
this.Last.Next = node;
this.Last = node;
}
this.Count++;
return node;
}
private void ThrowArgumentNullException(MyLinkedListNode<T> node)
{
if (node == null)
{
throw new ArgumentNullException();
}
}
public void Clear()
{
this.First = null;
this.Last = null;
this.Count = 0;
}
public bool Contains(T item)
{
if (item == null)
{
throw new ArgumentNullException();
}
MyLinkedListNode<T> tempNode = this.First;
while (tempNode != null)
{
if (item.Equals(tempNode.Value))
{
return true;
}
tempNode = tempNode.Next;
}
return false;
}
public bool Contains(T item, out MyLinkedListNode<T> node)
{
node = default(MyLinkedListNode<T>);
if (item == null)
{
throw new ArgumentNullException();
}
if (IsEmpty)
{
return false;
}
MyLinkedListNode<T> tempNode = this.First;
while (tempNode != null)
{
if (item.Equals(tempNode.Value))
{
node = tempNode;
return true;
}
tempNode = tempNode.Next;
}
return false;
}
public void CopyTo(T[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
if (IsEmpty)
{
return false;
}
MyLinkedListNode<T> node;
if (this.Contains(item, out node))
{
if (node == this.First && node != this.Last)
{
this.First = node.Next;
node.Next.Previous = null;
}
else if (node == this.Last && node != this.First)
{
this.Last = node.Previous;
node.Previous.Next = null;
}
else if (node != this.First && node != this.Last)
{
node.Previous.Next = node.Next;
node.Next.Previous = node.Previous;
}
else
{
this.First = this.Last = null;
}
this.Count--;
return true;
}
return false;
}
public bool IsEmpty
{
get
{
return this.Count == 0;
}
}
public IEnumerator<T> GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(this);
}
private class Enumerator : IEnumerator<T>
{
private T current;
private MyLinkedListNode<T> curNode;
private MyLinkedList<T> myLinkedList;
public Enumerator(MyLinkedList<T> myLinkedList)
{
this.myLinkedList = myLinkedList;
this.current = default(T);
this.curNode = myLinkedList.First;
}
public T Current
{
get { return current; }
}
public void Dispose()
{
Console.WriteLine("\n============================");
}
object IEnumerator.Current
{
get { return current; }
}
public bool MoveNext()
{
if (curNode != null)
{
current = curNode.Value;
curNode = curNode.Next;
return true;
}
else
{
return false;
}
}
public void Reset()
{
this.current = default(T);
this.curNode = myLinkedList.First;
}
}
}
}