using System;
using System.Collections.Generic;
using System.Text;
namespace DataStructure
{
/// <summary>
/// 双向链表类
/// </summary>
/// <typeparam name="T"></typeparam>
class DoubleLinkList<T> : IListDS<T>
{
private DoubleLinkItem<T> head;
public DoubleLinkItem<T> Head
{
get { return head; }
set { head = value; }
}
/// <summary>
/// 获取双向链表长度
/// </summary>
/// <returns></returns>
public int GetLength()
{
if (IsEmpty())
return 0;
int length = 1;
DoubleLinkItem<T> temp = head;
while (temp.Next != null)
{
temp = temp.Next;
length++;
}
return length;
}
/// <summary>
/// 清除双向链表所有数据
/// </summary>
public void Clear()
{
if (!IsEmpty())
{
DoubleLinkItem<T> temp = head;
while (temp.Next != null)
{
temp = temp.Next;
temp.Last = null;
}
temp = null;
}
}
/// <summary>
/// 判断双向链表是否为空
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
if (head == null)
return true;
else
return false;
}
/// <summary>
/// 判断双向链表是否已满
/// </summary>
/// <returns></returns>
public bool IsFull()
{
return false;
}
/// <summary>
/// 在双向链表的尾端添加一个新数据
/// </summary>
/// <param name="item"></param>
public void Append(T item)
{
DoubleLinkItem<T> temp = new DoubleLinkItem<T>(null, item, null);
if (IsEmpty())
{
this.head = temp;
return;
}
DoubleLinkItem<T> tempItem = GetListItem(this.GetLength() - 1);
tempItem.Next = temp;
}
/// <summary>
/// 在双向链表指定的位置插入一个新项
/// </summary>
/// <param name="item"></param>
/// <param name="index"></param>
public void Insert(T item, int index)
{
if (index < 0)
throw new Exception("插入位置不能小于0");
if (index > this.GetLength() + 1)
throw new Exception("插入位置超出链表长度");
if (index == 0)
{
DoubleLinkItem<T> temp = head;
this.head = new DoubleLinkItem<T>(null, item, temp);
return;
}
if (index == GetLength())
{
DoubleLinkItem<T> temp = GetListItem(index - 1);
temp.Next = new DoubleLinkItem<T>(temp, item, null);
return;
}
DoubleLinkItem<T> tempLast = GetListItem(index - 1);
DoubleLinkItem<T> tempNext = GetListItem(index);
tempLast.Next = new DoubleLinkItem<T>(tempLast, item, tempNext);
}
/// <summary>
/// 删除指定位置的双向链表项
/// </summary>
/// <param name="index"></param>
public void Delete(int index)
{
if (index < 0)
throw new Exception("删除位置不能小于0");
if (index > this.GetLength() - 1)
throw new Exception("插入位置超出链表长度");
if (index == 0)
{
this.head = this.head.Next;
if (!IsEmpty())
this.head.Last = null;
return;
}
if (index == this.GetLength() - 1)
{
DoubleLinkItem<T> temp = GetListItem(index);
temp.Last.Next = null;
return;
}
DoubleLinkItem<T> tempItem = GetListItem(index);
DoubleLinkItem<T> tempLast = tempItem.Last;
DoubleLinkItem<T> tempNext = tempItem.Next;
tempLast.Next = tempNext;
tempNext.Last = tempLast;
}
/// <summary>
/// 获取指定位置的双向链表项目,头项从0开始表示
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T GetItem(int index)
{
return GetListItem(index).Data;
}
/// <summary>
/// 获取指定位置的双向链表项目,头项从0开始
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public DoubleLinkItem<T> GetListItem(int index)
{
if (index < 0)
throw new Exception("索引不能小于0");
if (index > this.GetLength() - 1)
throw new Exception("索引超出列表总长度");
DoubleLinkItem<T> temp = head;
for (int i = 0; i < index; i++)
{
temp = temp.Next;
}
return temp;
}
/// <summary>
/// 根据给定的链表项的值查找该项处于链表哪个位置
/// 当其中有相同项时,默认返回排在前面的项
/// </summary>
/// <param name="value">子项的值</param>
/// <returns></returns>
public int Locate(T value)
{
if (!IsEmpty())
{
if (head.Data.Equals(value))
return 0;
DoubleLinkItem<T> temp = head;
int i = 1;
while (temp.Next != null)
{
temp = temp.Next;
if (temp.Data.Equals(value))
return i;
i++;
}
}
return -1;
}
}
/// <summary>
/// 双向链表子项类
/// </summary>
/// <typeparam name="T"></typeparam>
class DoubleLinkItem<T>
{
private DoubleLinkItem<T> last;
private DoubleLinkItem<T> next;
private T data;
public DoubleLinkItem<T> Last
{
set { last = value; }
get { return last; }
}
public DoubleLinkItem<T> Next
{
get { return next; }
set { next = value; }
}
public T Data
{
get { return data; }
set { data = value; }
}
/// <summary>
/// 构造函数,表示构造链表的中间子项,子项的前驱和后驱均不为空
/// 如果需要构造头项或尾项,只需要将相应的前驱和后驱设置为空即可
/// </summary>
/// <param name="last">前驱</param>
/// <param name="data">子项数据</param>
/// <param name="next">后驱</param>
public DoubleLinkItem(DoubleLinkItem<T> last, T data, DoubleLinkItem<T> next)
{
this.last = last;
this.data = data;
this.next = next;
}
}
}