zoukankan      html  css  js  c++  java
  • 顺序表

    线性表是最常用且最简单的一种数据结构。简言之,一个线性表是n个数据元素的有限序列。线性表的顺序表示指的是一组地址连续的存储单元依次存储线性表的数据元素。线性表的顺序存储结构是一种随机存取的存储结构。

    由于c#中的数组类型也有随机存取的特性,因此,通常采用数组来描述数据结构中的顺序存储结构。

    为了能够复用代码,采用泛型类的设计。

    这里要说明以下,由于.NET提供的关于线性表的类(如:ArrayLIst,SortedList)采用下标从0开始的索引值设计。所以,为了学习使用方便。以下代码中,关于“第i个”元素,都是从0开始算起的。

    1 using System;
    2  using System.Collections.Generic;
    3  using System.Linq;
    4  using System.Text;
    5
    6 namespace 线性表
    7 {
    8 public class SeqList<T> where T:IComparable<T>
    9 {
    10
    11 private int length; //线性表表的当前长度
    12 private const int INITIAL_SIZE = 10; //线性表存储空间的初始分配量
    13 private const int LIST_INCREMENT = 5; //线性表存储空间的分配增量
    14 private int listSize; //当前分配的存储容量
    15 private T[] lists; //数组,用于存储数据
    16
    17 #region 构造函数
    18
    19 public SeqList()
    20 {
    21 lists = new T[INITIAL_SIZE];
    22 this.length = 0;
    23 this.listSize = INITIAL_SIZE;
    24 }
    25
    26 public SeqList(int size)
    27 {
    28 if (size < 0)
    29 {
    30 throw new ArgumentException("ArgumentException:线性表长度不能小于0.");
    31 }
    32 lists = new T[size];
    33 this.length = 0;
    34 this.listSize = size;
    35 }
    36 #endregion
    37
    38 #region 属性和索引器
    39
    40 //线性表长度Length属性
    41 public int Length
    42 {
    43 get { return length; }
    44 }
    45
    46 //线性表容量Capacity属性
    47 public int Capacity
    48 {
    49 get { return listSize; }
    50 }
    51
    52 //索引器,可以使像使用数组一样引用线性表中的元素
    53 public T this[int index]
    54 {
    55 get { return lists[index]; }
    56 set { lists[index] = value; }
    57 }
    58 #endregion
    59
    60 /// <summary>
    61 /// 如果线性表容量不够用,增加容量。
    62 /// </summary>
    63 private void enlargeIfFull()
    64 {
    65 if (this.length == this.listSize)
    66 {
    67 int bigger = length + LIST_INCREMENT;
    68 this.listSize = bigger;
    69
    70 T[] moreLists = new T[bigger];
    71 this.lists.CopyTo(moreLists, 0); //复制元素到新的数组
    72
    73 this.lists = moreLists; //指向新的数组
    74 }
    75 }
    76
    77 #region 顺序表常规操作
    78 /// <summary>
    79 /// 获取线性表长度
    80 /// </summary>
    81 /// <returns>长度</returns>
    82 public int GetLength()
    83 {
    84 return this.length;
    85 }
    86
    87 /// <summary>
    88 /// 清空线性表
    89 /// </summary>
    90 public void Clear()
    91 {
    92 this.length = 0;
    93 }
    94
    95 /// <summary>
    96 /// 判断是否为空
    97 /// </summary>
    98 /// <returns></returns>
    99 public bool IsEmpty()
    100 {
    101 return length == 0;
    102 }
    103
    104 /// <summary>
    105 /// 添加操作,在末尾添加元素
    106 /// </summary>
    107 /// <param name="item">需要添加的元素</param>
    108 public void Add(T item)
    109 {
    110 enlargeIfFull();
    111
    112 lists[length++] = item;
    113 }
    114
    115 /// <summary>
    116 /// 插入操作,i为从0开始的索引值
    117 /// </summary>
    118 /// <param name="i">索引值,从0开始</param>
    119 /// <param name="item">插入的元素</param>
    120 public void Insert(int i, T item)
    121 {
    122 if (i < 0 || i > this.length)
    123 {
    124 throw new ArgumentException("ArgumentException:参数不合法,无法执行插入操作");
    125 }
    126
    127 enlargeIfFull();
    128
    129 for (int j = this.length - 1; j >= i; j--)
    130 {
    131 lists[j + 1] = lists[j]; //插入位置及之后的元素后移
    132 }
    133
    134 lists[i] = item; //插入item
    135 this.length++; //表长增1
    136
    137 }
    138
    139 /// <summary>
    140 /// 删除操作
    141 /// </summary>
    142 /// <param name="i">索引值,从0开始</param>
    143 /// <returns></returns>
    144 public T Delete(int i)
    145 {
    146 if (i < 0 || i > this.length-1)
    147 {
    148 throw new ArgumentException("ArgumentException:参数不合法,无法执行删除操作");
    149 }
    150
    151 T del = lists[i]; //被删除元素赋值给del
    152
    153 for (int j = i; j < this.length - 1; j++)
    154 {
    155 lists[j] = lists[j + 1]; //被删除元素之后的元素前移
    156 }
    157
    158 this.length--; //表长减1
    159 return del; //返回被删除元素
    160 }
    161
    162 /// <summary>
    163 /// 获取元素,该方法与索引器效果相同
    164 /// </summary>
    165 /// <param name="i">索引值,从0开始</param>
    166 /// <returns>元素值</returns>
    167 public T GetElem(int i)
    168 {
    169 if (i < 0|| i > this.length-1)
    170 {
    171 throw new ArgumentException("ArgumentException:参数不合法,无法获取元素");
    172 }
    173
    174 return lists[i];
    175 }
    176
    177 /// <summary>
    178 /// 定位元素位置,相当于IndexOf方法
    179 /// </summary>
    180 /// <param name="item">元素</param>
    181 /// <returns>索引值,从0开始</returns>
    182 public int Locate(T item)
    183 {
    184 int i = 0; //i的初始值为第0个元素的位置
    185
    186 while (i < this.length && !item.Equals(lists[i]))
    187 {
    188 i++;
    189 }
    190
    191 if (i <=this.length-1)
    192 return i;
    193 else
    194 return -1;
    195
    196 }
    197
    198 /// <summary>
    199 /// 倒置操作
    200 /// </summary>
    201 public void Reverse()
    202 {
    203 if (this.length == 0)
    204 {
    205 throw new InvalidOperationException("InvalidOperationException:线性表为空,无法执行倒置操作");
    206 }
    207
    208 int i = 0;
    209 int j = this.length / 2;
    210 while (i < j)
    211 {
    212 T tmp = lists[i];
    213 lists[i] = lists[this.length-1- i];
    214 lists[this.length-1- i] =tmp;
    215 i++;
    216 }
    217 }
    218
    219 /// <summary>
    220 /// 合并操作,前提条件是当前线性表和other线性表按非递减有序排列
    221 /// </summary>
    222 /// <typeparam name="TItem">泛型</typeparam>
    223 /// <param name="other">另外一个线性表</param>
    224 /// <returns>合并后的线性表</returns>
    225 public SeqList<T> Merge<TItem>(SeqList<T> other) where TItem:T
    226 {
    227 SeqList<T> sList = new SeqList<T>();
    228 int i = 0; //当前线性表的循环变量
    229 int j = 0; //other线性表的循环变量
    230 while (i <= this.length - 1 && j <= other.length - 1)
    231 {
    232 if (lists[i].CompareTo(other[j]) < 0 || lists[i].CompareTo(other[j]) == 0)
    233 {
    234 sList.Add(lists[i++]);
    235 }
    236 else
    237 {
    238 sList.Add(other[j++]);
    239 }
    240 }
    241
    242 while (i <= this.length - 1)
    243 {
    244 sList.Add(lists[i++]);
    245 }
    246 while (j <= other.length-1)
    247 {
    248 sList.Add(other[j++]);
    249 }
    250 return sList;
    251 }
    252
    253 /// <summary>
    254 ///并集操作,将当前线性表表中没有,other中有的元素插入表末尾
    255 /// </summary>
    256 /// <param name="other"></param>
    257 public void Union(SeqList<T> other)
    258 {
    259 int len = this.length;
    260 for (int i = 0; i < other.length; i++)
    261 {
    262 T tmp =other[i];
    263 if (this.Locate(tmp) == -1)
    264 {
    265 this.Insert(len++, tmp);
    266 }
    267
    268 }
    269 }
    270 #endregion
    271
    272 }
    273 }
  • 相关阅读:
    吊打面试官系列:Redis 性能优化的 13 条军规大全
    Laravel 7.6 发布
    Laravel 8 新功能:使用 schema:dump 来加速 Migration 和测试
    php中常用的4种运行方式
    基于 Redis 的订阅与发布
    [ida]使用pycharm编写IDApython
    visual studio 配置使生成的pdb文件中包含所有符号
    D/B位、一致与非一致代码段、向下拓展的实验与总结
    [debug] CE指针扫描扫出来为空
    error LNK2019: 无法解析的外部符号 _main,该符号在函数___tmainCRTStartup 中被引用
  • 原文地址:https://www.cnblogs.com/dongliyang/p/2001464.html
Copyright © 2011-2022 走看看