C# 顺序表的原理及实现

题外话:这两天感觉转性了,只想学习不想玩了,难道要成为大神了?哈哈哈哈

PS: 本文的重点代码代码代码!而不是数据结构的一些基础概念和分类;
完全没接触过的同学,可以去看B站王卓教授的视频。


1.什么是顺序表?

  • 逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构。

  • 线性表的顺序存储结构,必须占用一片连续的存储空间

  • 这货和链表什么关系?

    • 恭喜你! 盲僧,你发现了华点!!
    • 顺序表和链表本质上都是线性表,但是!!!
    • 顺序表他不是内存空间连续嘛;
    • 链表的内存空间不一定连续,东一块西一块也行,这就是他俩的差别。

2.什么时候使用顺序表?

  • 数据访问量比较大,且新增、删除操作不频繁的数据。

3.顺序表和数组的关系

  • 可以理解为数组是顺序表的一种实现,数组就是顺序表;
  • 因为高级语言都帮你实现了数组的底层设计,所以开发者当他是顺序表直接拿来用即可

4.总结:什么是顺序表?

  • 逻辑上相邻,存储结构也相邻的数据结构,叫顺序表。

5.代码实现

namespace YoyoCode
{
    //顺序表
    internal class SqList<T> where T : class
    {
        /// <summary>
        /// 数组默认最大容量
        /// </summary>
        public int MaxSize = 8;
        /// <summary>
        /// 存放元素的数组
        /// </summary>
        private T[] _array;
        /// <summary>
        /// 数组中元素的数量
        /// </summary>
        public int Count = 0;

        public SqList()
        {
            _array = new T[MaxSize];
        }

        public SqList(int maxSize)
        {
            MaxSize = maxSize;
            _array = new T[MaxSize];
        }
        /// <summary>
        /// 在顺序表尾端添加元素
        /// </summary>
        /// <param name="value">添加的值,类型为T</param>
        /// <returns>bool,是否添加成功</returns>
        public bool Add(T value)
        {
            if (Count == MaxSize)
            {
                Console.WriteLine("数组已满,无法添加元素!");
                return false;
            }
            _array[Count++] = value;
            return true;
        }
        /// <summary>
        /// 获取对应索引的元素
        /// </summary>
        /// <param name="idx">索引值</param>
        /// <returns>T</returns>
        public T? Get(int idx)
        {
            if (idx >= Count || idx < 0)
            {
                return null;
            }
            return _array[idx];
        }
        /// <summary>
        /// 获取顺序表最后一个元素
        /// </summary>
        /// <returns>T</returns>
        public T? GetLast() {
            if (IsEmpty())
            {
                return null;
            }
            return _array[Count- 1];
        }
        /// <summary>
        /// 顺序表是否为空
        /// </summary>
        /// <returns>bool,表是否为空</returns>
        public bool IsEmpty()
        {
            return Count == 0;
        }
        /// <summary>
        /// 清空顺序表(逻辑清空)
        /// </summary>
        public void Clear()
        {
            //逻辑清空(遍历_array时不用foreach,而是用Count)
            Count= 0;
        }
        /// <summary>
        /// 在对应的索引插入元素,
        /// 不支持不连续的插入,例如数组总共3个元素,索引从0-2,你要在索引4插入,非法
        /// </summary>
        /// <param name="value"></param>
        /// <param name="idx"></param>
        /// <returns>bool,是否插入成功</returns>
        public bool Insert(T value, int idx) { 
            if(Count == MaxSize)
            {
                Console.WriteLine("数组已满,无法添加元素!");
                return false;
            }
            if (idx < 0 || idx > Count)
            {
                Console.WriteLine("插入位置有误!");
                return false;
            }
            //从后向前插入,省一个空间
            for (int i = Count; i > idx; i--)
            {
                _array[i] = _array[i - 1];
            }
            _array[idx] = value;
            Count++;
            return true;
        }
        /// <summary>
        /// 删除某个索引的元素
        /// </summary>
        /// <param name="idx">被删除元素的索引</param>
        /// <returns>bool,是否删除成功</returns>
        public bool RemoveAt(int idx)
        {
            if (idx < 0 || idx >= Count)
            {
                Console.WriteLine("插入位置有误!");
                return false;
            }
            //从前向后遍历,省一个空间
            for (int i = idx; i < Count; i++)
            {
                _array[i] = _array[i + 1];
            }
            Count--;
            return true;
        }
        /// <summary>
        /// 遍历顺序表中所有的元素,并执行你希望的操作。
        /// 例如:你可以通过该函数实现Contains的功能,判断表中是否存在某个元素。
        /// </summary>
        /// <param name="func">返回值为bool,参数为T的委托,bool为true时会打断循环</param>
        public void Traverse(Func<T, bool> func)
        {
            for (int i = 0; i < Count; i++)
            {
                if (func(_array[i])) {
                    break;
                }
            }
        }
    }
}

说明

  1. 该类使用了泛型,且必须是类类型才可以。.
  2. 该类提供了遍历函数Traverse,可通过传入委托实现各种你需要的遍历操作。

6.都有数组了,为什么要自己实现?

  • 首先,我在学数据结构,只有手敲一遍才能理解该结构的优缺点。
  • 其次,C#提供的数组其实也不是很方便,缺少很多对数组的操作,比如插入删除遍历等,所以自己实现了,以后自己代码也能用哦。
  • 最后,,,啊。。。嗯。。。好像没了hhh。

7.顺序表的优缺点

  • 优点
    • 存储密度大,即存储结构中(_array),100%的空间都给到元素使用了。
    • 可随机存取表中任意元素,时间复杂度为O(1)
  • 缺点
    • 插入、删除、查找的时间复杂度为O(n)
    • 浪费存储空间,且静态存储(数组大小固定了,无法扩容)

结束语: 这一鸽就是好几个月哈哈哈,后面会增加几篇数据结构相关的文章。大学的《数据结构与算法》教材教啥我就写啥。
你一定要支棱起来啊!!!让看不起你的人对你刮目相看!!!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值