用C#实现双向链表(使用泛型)

来源:互联网 发布:python 2.7支持中文吗 编辑:程序博客网 时间:2024/05/22 02:06
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;
}
}
}

原创粉丝点击