用C#写的数据结构类库(2)——单链表
二、单链表
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace DataStructure_CS
{
//结点
class S_Node<T>
{
public T m_data;
public int m_next;
public S_Node()
{
m_data = default(T);
m_next = -1;
}
public S_Node(T e, int next)
{
m_data = e;
m_next = next;
}
}
//单链表
public class S_LinkedList<T>
{
#region 私有变量
private List<S_Node<T>> m_list = new List<S_Node<T>>(); //存储元素的数组
private List<int> m_pos = new List<int>(); //数组中空闲的位置
#endregion
#region 公共函数
//构造函数
public S_LinkedList()
{
m_list.Add(new S_Node<T>());
}
//初始化单链表
public Status Initialize()
{
try
{
m_list = new List<S_Node<T>>();
m_list.Add(new S_Node<T>());
return Status.OK;
}
catch
{
return Status.ERROR;
}
}
//清空单链表
public Status Clear()
{
return Initialize();
}
//判断单链表是否为空
public bool IsEmpty()
{
return m_list[0].m_next == -1 ? true : false;
}
//获得表的长度
public int Length()
{
int count = 0;
int temp = 0;
while (m_list[temp].m_next != -1)
{
temp = m_list[temp].m_next;
count++;
}
return count;
}
//获得第index个元素
public Status GetElement(int index,ref T e)
{
if (index <= 0)
{
return Status.ERROR;
}
int count = 0;
int temp = 0;
while (m_list[temp].m_next != -1 && count != index)
{
temp = m_list[temp].m_next;
count++;
}
if (count != index)
{
return Status.ERROR;
}
else
{
e = m_list[temp].m_data;
return Status.OK;
}
}
//获得值为e的元素的位序,若不存在则返回0
public int LocateElement(T e)
{
int temp = 0;
int count = 0;
while (m_list[temp].m_next != -1 && !m_list[temp].m_data.Equals(e))
{
temp = m_list[temp].m_next;
count++;
}
if (!m_list[temp].m_data.Equals(e))
{
return 0;
}
else
{
return count;
}
}
//获得元素e的前一个元素
public Status PriorElement(T e, ref T pre_e)
{
int index = LocateElement(e);
return GetElement(index - 1, ref pre_e);
}
//获得元素e的下一个元素
public Status NextElement(T e, ref T next_e)
{
int index = LocateElement(e);
return GetElement(index + 1, ref next_e);
}
//在第index个位置插入新的数据元素e,i应满足1<=index<=m_length+1
public Status Insert(int index, T e)
{
if (index <= 0)
{
return Status.ERROR;
}
//找到插入位置之前的一个元素的指针
int temp = 0;
int count = 0;
while (m_list[temp].m_next != -1 && count != index - 1)
{
temp = m_list[temp].m_next;
count++;
}
if (count != index - 1)
{
return Status.ERROR;
}
//建立新元素
int p_item; //新元素的指针
if (m_pos.Count != 0) //如果m_pos非空,取其中第一个位置
{
p_item = m_pos[0];
m_pos.RemoveAt(0);
}
else //如果m_pos为空,则需分配一块新的空间
{
m_list.Add(new S_Node<T>());
p_item = m_list.Count - 1;
}
//插入元素
m_list[p_item].m_data = e;
m_list[p_item].m_next = m_list[temp].m_next;
m_list[temp].m_next = p_item;
return Status.OK;
}
//将一个元素插到表尾
public Status Append(T e)
{
int temp = 0;
while (m_list[temp].m_next != -1)
{
temp = m_list[temp].m_next;
}
//建立新元素
int p_item; //新元素的指针
if (m_pos.Count != 0) //如果m_pos非空,取其中第一个位置
{
p_item = m_pos[0];
m_pos.RemoveAt(0);
}
else //如果m_pos为空,则需分配一块新的空间
{
m_list.Add(new S_Node<T>());
p_item = m_list.Count - 1;
}
//插入元素
m_list[p_item].m_data = e;
m_list[p_item].m_next = m_list[temp].m_next;
m_list[temp].m_next = p_item;
return Status.OK;
}
//删除第index个数据元素,并用e返回其值,index应满足1<=index<=m_length
public Status Delete(int index, ref T e)
{
if (index <= 0)
{
return Status.ERROR;
}
int temp = 0;
int count = 0;
while (m_list[temp].m_next != -1 && count != index - 1)
{
temp = m_list[temp].m_next;
count++;
}
if (count != index - 1)
{
return Status.ERROR;
}
m_pos.Add(m_list[temp].m_next); //将删除的位置标为空闲
m_list[temp].m_next = m_list[m_list[temp].m_next].m_next; //修改指针
return Status.OK;
}
#endregion
}
}
借用List容器存放数据,用下标实现指针的功能,类似于静态链表的实现方式。另外用一个List<int>容器收集被删除元素的下标,即空闲的位置,当插入新的元素的时候,如果有空闲位置,则直接放到空闲位置上,而不需分配新的空间,这作为一种垃圾回收机制。
没有使用指针,虽然理论上C#也可以用指针,但是这是在CLR类库中,而且还用到了泛型,我尝试过后觉得用指针实现几乎是不可能的。
文件S_LinkedList.cs
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace DataStructure_CS
{
//结点
class S_Node<T>
{
public T m_data;
public int m_next;
public S_Node()
{
m_data = default(T);
m_next = -1;
}
public S_Node(T e, int next)
{
m_data = e;
m_next = next;
}
}
//单链表
public class S_LinkedList<T>
{
#region 私有变量
private List<S_Node<T>> m_list = new List<S_Node<T>>(); //存储元素的数组
private List<int> m_pos = new List<int>(); //数组中空闲的位置
#endregion
#region 公共函数
//构造函数
public S_LinkedList()
{
m_list.Add(new S_Node<T>());
}
//初始化单链表
public Status Initialize()
{
try
{
m_list = new List<S_Node<T>>();
m_list.Add(new S_Node<T>());
return Status.OK;
}
catch
{
return Status.ERROR;
}
}
//清空单链表
public Status Clear()
{
return Initialize();
}
//判断单链表是否为空
public bool IsEmpty()
{
return m_list[0].m_next == -1 ? true : false;
}
//获得表的长度
public int Length()
{
int count = 0;
int temp = 0;
while (m_list[temp].m_next != -1)
{
temp = m_list[temp].m_next;
count++;
}
return count;
}
//获得第index个元素
public Status GetElement(int index,ref T e)
{
if (index <= 0)
{
return Status.ERROR;
}
int count = 0;
int temp = 0;
while (m_list[temp].m_next != -1 && count != index)
{
temp = m_list[temp].m_next;
count++;
}
if (count != index)
{
return Status.ERROR;
}
else
{
e = m_list[temp].m_data;
return Status.OK;
}
}
//获得值为e的元素的位序,若不存在则返回0
public int LocateElement(T e)
{
int temp = 0;
int count = 0;
while (m_list[temp].m_next != -1 && !m_list[temp].m_data.Equals(e))
{
temp = m_list[temp].m_next;
count++;
}
if (!m_list[temp].m_data.Equals(e))
{
return 0;
}
else
{
return count;
}
}
//获得元素e的前一个元素
public Status PriorElement(T e, ref T pre_e)
{
int index = LocateElement(e);
return GetElement(index - 1, ref pre_e);
}
//获得元素e的下一个元素
public Status NextElement(T e, ref T next_e)
{
int index = LocateElement(e);
return GetElement(index + 1, ref next_e);
}
//在第index个位置插入新的数据元素e,i应满足1<=index<=m_length+1
public Status Insert(int index, T e)
{
if (index <= 0)
{
return Status.ERROR;
}
//找到插入位置之前的一个元素的指针
int temp = 0;
int count = 0;
while (m_list[temp].m_next != -1 && count != index - 1)
{
temp = m_list[temp].m_next;
count++;
}
if (count != index - 1)
{
return Status.ERROR;
}
//建立新元素
int p_item; //新元素的指针
if (m_pos.Count != 0) //如果m_pos非空,取其中第一个位置
{
p_item = m_pos[0];
m_pos.RemoveAt(0);
}
else //如果m_pos为空,则需分配一块新的空间
{
m_list.Add(new S_Node<T>());
p_item = m_list.Count - 1;
}
//插入元素
m_list[p_item].m_data = e;
m_list[p_item].m_next = m_list[temp].m_next;
m_list[temp].m_next = p_item;
return Status.OK;
}
//将一个元素插到表尾
public Status Append(T e)
{
int temp = 0;
while (m_list[temp].m_next != -1)
{
temp = m_list[temp].m_next;
}
//建立新元素
int p_item; //新元素的指针
if (m_pos.Count != 0) //如果m_pos非空,取其中第一个位置
{
p_item = m_pos[0];
m_pos.RemoveAt(0);
}
else //如果m_pos为空,则需分配一块新的空间
{
m_list.Add(new S_Node<T>());
p_item = m_list.Count - 1;
}
//插入元素
m_list[p_item].m_data = e;
m_list[p_item].m_next = m_list[temp].m_next;
m_list[temp].m_next = p_item;
return Status.OK;
}
//删除第index个数据元素,并用e返回其值,index应满足1<=index<=m_length
public Status Delete(int index, ref T e)
{
if (index <= 0)
{
return Status.ERROR;
}
int temp = 0;
int count = 0;
while (m_list[temp].m_next != -1 && count != index - 1)
{
temp = m_list[temp].m_next;
count++;
}
if (count != index - 1)
{
return Status.ERROR;
}
m_pos.Add(m_list[temp].m_next); //将删除的位置标为空闲
m_list[temp].m_next = m_list[m_list[temp].m_next].m_next; //修改指针
return Status.OK;
}
#endregion
}
}