用C#實現雙向鏈表(使用泛型)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DoubleLinkedList
{
class DoubleLinkedList
{
class Node
{
// 指向上一個元素指針
public Node Previous { get; set; }

// 指向下一個元素指針
public Node Next { get; set; }

// 數據,可以是任何類型
public int Data { get; set; }

public int index { set; get; }

/// <summary>
/// 創建一個新的節點
/// </summary>
public Node(int data)
{
// 給數據賦值
Data = data;
// 給前後指針賦值爲空
Previous = null;
Next = null;
index = -1;
}
}

// 頭指針
private Node Head = null;

// 尾指針
private Node Tail = null;

// 鏈表長度
private int count = 0;

private int tailIndex = 0;

/// <summary>
/// 創建一個空的鏈表
/// </summary>
public DoubleLinkedList()
{
count = 0;
Head = null;
Tail = null;
tailIndex = 0;
}

/// <summary>
/// 獲得鏈表長度
/// </summary>
public int GetCount()
{
return count;
}

public void MyQuickSort()
{
MyQSort(0, GetCount() - 1);
}

private void MyQSort(int low, int high)
{
if (low < high)
{
int pivot = MyPartition(low, high);
MyQSort(low, pivot - 1);
MyQSort(pivot + 1, high);
}
}

private int MyPartition(int low, int high)
{
Node h = GetNoByVI(low);
int pivotIndex = h.index;
Node tmp = h;
Node t = GetNoByVI(high);
while (h != t)
{
while (h != t && tmp.Data <= t.Data)
{
t = t.Previous;
}
SetVI(h, t.index);
while (h != t && tmp.Data >= h.Data)
{
h = h.Next;
}
SetVI(t, h.index);
}
h.index = pivotIndex;
return h.index;
}

private int GetEleByVI(int index)
{
Node p = GetNoByVI(index);
if (p != null)
{
return p.index;
}
return -1;
}

private Node GetNoByVI(int index)
{
Node p = Head;
while (p != null)
{
if (index == p.index)
{
return p;
}
p = p.Next;
}
return null;
}

void SetVI(Node node, int index)
{
Node p = Head;
while (p != null)
{
if (p == node)
{
p.index = index;
break;
}
p = p.Next;
}
}

private int PartitionAscending(int low, int high)
{
int pivotKey = this[low];
while (low < high)
{
while (low < high && this[high] >= pivotKey)
{
high--;
}
this[low] = this[high];
while (low < high && this[low] <= pivotKey)
{
low++;
}
this[high] = this[low];
}
this[low] = pivotKey;
return low;
}

private void QSortAscending(int low, int high)
{
if (low < high)
{
int pivot = PartitionAscending(low, high);
QSortAscending(low, pivot - 1);
QSortAscending(pivot + 1, high);
}
}

public void QuickSortAscending()
{
QSortAscending(0, GetCount() - 1);
}

private int PartitionDecending(int low, int high)
{
int pivotKey = this[low];
while (low < high)
{
while (low < high && this[high] <= pivotKey)
{
high--;
}
this[low] = this[high];
while (low < high && this[low] >= pivotKey)
{
low++;
}
this[high] = this[low];
}
this[low] = pivotKey;
return low;
}

private void QSortDecending(int low, int high)
{
if (low < high)
{
int pivot = PartitionDecending(low, high);
QSortDecending(low, pivot - 1);
QSortDecending(pivot + 1, high);
}
}

public void QuickSortDecending()
{
QSortDecending(0, GetCount() - 1);
}

/// <summary>
/// 在尾部添加元素
/// </summary>
public void Add(int item)
{
// 先創建一個新的節點
Node newNode = new Node(item);
newNode.index = tailIndex;

// 如果鏈表爲空
if (IsEmpty())
{
Head = newNode;
Tail = newNode;
}
// 鏈表不空
else
{
// 將兩個節點相連
Tail.Next = newNode;
newNode.Previous = Tail;

// 尾指針後移
Tail = newNode;
}
// 將新創建的指針置空
newNode = null;
// 鏈表長度加1
count++;

tailIndex++;
}

/// <summary>
/// 利用索引取元素
/// </summary>
/// <param name="index">元素位置索引</param>
/// <returns>index索引所對應的元素值</returns>
public int this[int index]
{
get
{
if (index < 0 || index >= count)
{
throw new Exception("索引錯誤!");
}

Node newNode = null;
newNode = Head;

int i = 0;
// 找到index所對應的元素位置
while (newNode.Next != null && i < index)
{
newNode = newNode.Next;
i++;
}
return newNode.Data;
}
set
{
if (index < 0 || index >= count)
{
throw new Exception("索引錯誤!");
}

Node newNode = null;
newNode = Head;
int i = 0;
while (newNode.Next != null && i < index)
{
newNode = newNode.Next;
i++;
}
newNode.Data = value;
}
}

/// <summary>
/// 向鏈表中插入數據
/// </summary>
public void Insert(int item, int index)
{
// 如果爲空的鏈表
if (IsEmpty())
{
Add(item);
return;
}

// 索引超出範圍
if (index < 0 || index >= count)
{
throw new Exception("索引錯誤!");
}

Node beforeNode = null;
int i = 0;

// 如果在第一個位置插入
if (0 == index)
{
beforeNode = new Node(item);
beforeNode.Next = Head;
Head.Previous = beforeNode;
Head = beforeNode;
beforeNode = null;
count++;
tailIndex++;
return;
}

beforeNode = Head;
while (beforeNode.Next != null && i < index - 1)
{
beforeNode = beforeNode.Next;
i++;
}

Node toInsert = new Node(item);
Node tNode = beforeNode.Next;
toInsert.Next = tNode;
toInsert.Previous = beforeNode;
beforeNode.Next = toInsert;
tNode.Previous = toInsert;

count++;
tailIndex++;
}

/// <summary>
/// 刪除指定值的元素
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Remove(int item)
{
if (IsEmpty())
{
return false;
}

Node p = Head;

while (p != null)
{
if (item.Equals(p.Data))
{
// 刪除的是第一個節點
if (p == Head)
{
p = p.Next;
Head = p;
count--;
tailIndex--;
return true;
}

// 刪除的是最後一個節點
if (p == Tail)
{
Tail = p.Previous;
// 把尾部指針置空
Tail.Next = null;
p = null;
count--;
tailIndex--;
return true;
}

// 刪除的是中間節點
Node previous = p.Previous;
Node next = p.Next;
previous.Next = next;
next.Previous = previous;
p.Next = null;
p.Previous = null;
p = null;
count--;
tailIndex--;
return true;
}
p = p.Next;
}
return false;
}

/// <summary>
/// 刪除index所在位置的元素
/// </summary>
/// <param name="index">索引值</param>
public void RemoveAt(int index)
{
// 索引錯誤
if (index < 0 || index >= GetCount())
{
throw new Exception("索引錯誤!");
}

// 循環指針
Node p = Head;

// 刪除頭節點
if (0 == index)
{
p = p.Next;
Head.Next = null;
Head = p;
Head.Previous = null;
count--;
tailIndex--;
return;
}

// 刪除尾節點
if (GetCount() - 1 == index)
{
p = Tail;
Tail = Tail.Previous;
Tail.Next = null;
p.Next = null;
p.Previous = null;
p = null;
count--;
tailIndex--;
return;
}

p = Head;
int i = 0;
while (p.Next != null && i < index)
{
p = p.Next;
i++;
}
p.Previous.Next = p.Next;
p.Next.Previous = p.Previous;
p.Next = null;
p.Previous = null;
p = null;
count--;
tailIndex--;
}


/// <summary>
/// 打印鏈表
/// </summary>
public void PrintElements()
{
// 如果鏈表爲空
if (IsEmpty())
{
return;
}

Node p = Head;
while (p != null)
{
Console.Write(p.Data + " ");
p = p.Next;
}
Console.WriteLine();
}

/// <summary>
/// 清空鏈表
/// </summary>
public void Clear()
{
// 不用判斷是否爲空,是空的話也會正常執行
Node p = Head;
while (p != null)
{
p = p.Next;
Head = null;
Head = p;
}
Tail = null;
count = 0;
}

/// <summary>
/// 判斷鏈表是否爲空
/// </summary>
public bool IsEmpty()
{
return count == 0;
}
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章