上文讲了一些数据结构的基本概念,现在开始进入正题,今天学习最简单的线性表,线性表分为顺序存储结构和链式存储结构,本文讲顺序存储结构的线性表。
在C#的面向对象的世界中,我们一般都会对一个东西进行抽象,线性表的接口如下(只定义了一些最基本的操作,一些复杂的操作都是基于这些基本的操作组合实现的):
/// <summary> /// c#线性表接口 /// </summary> public interface ICsharpList<T> { /// <summary> /// 指示线性表是否为空 /// </summary> /// <returns></returns> bool IsListEmpty(); /// <summary> /// 清空线性表 /// </summary> void ClearList(); /// <summary> /// 将第i个位置的元素返回 /// </summary> /// <param name="i"></param> /// <returns></returns> T GetItem(int i); /// <summary> /// 定位元素item在线性表中的位置,若不存在则返回-1 /// </summary> /// <param name="item"></param> /// <returns></returns> int LocateItem(T item); /// <summary> /// 在第i个位置插入元素item /// </summary> /// <param name="i"></param> /// <param name="item"></param> void ListInsert(int i, T item); /// <summary> /// 删除线性表第i个位置的元素,并返回该删除的元素 /// </summary> /// <param name="i"></param> /// <returns></returns> T ListDelete(int i); /// <summary> /// 获取线性表的长度 /// </summary> /// <returns></returns> int ListLength(); }
顺序存储结构的线性表实现如下:
/// <summary> /// 顺序存储结构线性表 /// </summary> public class CsharpSqList<T> : ICsharpList<T> { /// <summary> /// 最大长度 /// </summary> private readonly int _maxLength; /// <summary> /// 通过数组来实现顺序线性表 /// </summary> public T[] Arrary { get; set; } /// <summary> /// 指示线性表的长度 /// </summary> public int Length { get; set; } /// <summary> /// 构造函数 /// </summary> /// <param name="maxLength"></param> public CsharpSqList(int maxLength) { _maxLength = maxLength; Arrary = new T[_maxLength]; } /// <summary> /// 索引器 /// </summary> /// <param name="index"></param> /// <returns></returns> public T this[int index] { get { if (index >= 0 && index <= _maxLength - 1) return Arrary[index]; return default(T); } set { if (index >= 0 && index <= _maxLength - 1) Arrary[index] = value; } }
/// <summary> /// 清空线性表 /// </summary> /// <param name="index"></param> /// <returns></returns>
public void ClearList()
{
if (Length == 0)
return;
for (var i = 0; i < Length; i++)
{
Arrary[i] = default(T);
}
Length = 0;
} /// <summary> /// 获取第i个元素 /// </summary> /// <param name="i"></param> /// <returns></returns> public T GetItem(int i) { if (IsListEmpty()) throw new Exception("空线性表"); if(i<0||i>Length-1) throw new Exception("非法参数"); return Arrary[i]; } /// <summary> /// 是否为空线性表 /// </summary> /// <returns></returns> public bool IsListEmpty() { return Length == 0; } /// <summary> /// 删除第i个元素 /// </summary> /// <param name="i"></param> /// <returns></returns> public T ListDelete(int i) { if (IsListEmpty()) throw new Exception("空线性表"); if (i < 0 || i > Length - 1) throw new Exception("非法参数"); var item = this[i];//保存被删除的元素 if (i < Length - 1) //如果删除的元素不是最后一个则将后继的元素往前移动一步 { for (var j = i; j < Length; j++) { Arrary[j] = Arrary[j + 1]; } } Length--;//将长度减一 return item; } /// <summary> /// 插入一个元素到第i个位置 /// </summary> /// <param name="i"></param> /// <param name="item"></param> public void ListInsert(int i, T item) { if(Length==_maxLength) throw new Exception("线性表已满"); if(i<0||i>Length) throw new Exception("非法参数"); if (i < Length - 1) //如果插入的元素不是最后一个则将后继的元素往后移动一步 { for (var j = Length-1; j > i; j--) { Arrary[j + 1] = Arrary[j]; } } Arrary[i] = item; Length++;//长度加一 } /// <summary> /// 获取长度 /// </summary> /// <returns></returns> public int ListLength() { return Length; } /// <summary> /// 定位某个元素的第一个位置,若不存在则返回-1 /// </summary> /// <param name="item"></param> /// <returns></returns> public int LocateItem(T item) { for (var i = 0; i < Length; i++) { if (Arrary[i].Equals(item)) return i; } return -1; } }
代码比较简单,就不一一解释了。