欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#数据结构学习:线性结构之顺序表

程序员文章站 2022-07-13 13:40:10
...

什么是线性表

上篇我们提及到了单向链表的具体功能和实现,这次我们来学习一下线性表之顺序表的功能与实现。
通过前面问题的启示:
①同一个问题可以有不同的存储方法。
②这一类问题都是有序线性序列的组织和管理。

我们就把这类有序线性序列称作为线性表,数据结构最常见的存储方式要么是数组存储,要么是链表存储

总结一下
线性表:由同类型数据元素构成有序序列的线性结构
①表中元素个数为线性表的长度
②线性表没有元素时,称为空表
③表起始位置叫表头,表结束位置叫表尾

线性表的抽象数据类型描述

类型名称:线性表(List)
数据对象集:线性表是n(≥0)个元素构成的有序序列(a1,a2…an)
操作集:线性表L∈List,整数i表示位置,元素X∈ElementType(整型,结构,实型等)
其中操作集有以下操作:
①List MakeEmpty():初始化一个空线性表L;
②ElementType FindKth(int k,List L):根据位序k,返回相应元素
③int Find(ElementType X,List L):在线性表中查找X元素第一次出现的位置
④void Insert(ElementType X,int i,List L):在位序i前插入新元素X
⑤void Delete(int i,List L):删除指定位序i的元素
⑥int Length(List L):返回表的长度n

下面是顺序表的具体实现和定义:

class SeqList<T> 
    {
        private T[] Name;//顺序表表名
        private int Size;//顺序表当前最大的容量
        private int last;//最后的索引值

        public SeqList(int size)//初始化函数
        {
            this.Size = size;
            Name = new T[size];
        }

        public int Find(T Value)//找寻第一次出现的位置
        {
            for (int i = 0; i < Size; i++)
            {
                if (Name[i].Equals(Value))
                {
                    return i;
                }
            }
            return -1;
        }

        public T GetVaule(int Index)
        {
            if (Index > Size || Index < 0)
            {
                throw new Exception("索引超出范围");
            }
            T value = Name[Index];
            return value;
        }

        public void Insert(T Value, int Index)//在index前面插入数据
        {
            if (Index>Size||Index<0)
            {
                throw new Exception("索引超出范围");
            }

            for (int i = Size-1; i >= Index; i--)//往后移一位
            {
                Name[i] = Name[i - 1];
            }
            Name[Index] = Value;
            last++;
        }


        public void Add(T Value)
        {
            Name[last] = Value;
            last++;
        }

        public void Delete(T Value, int Index)
        {
            if (Index > Size || Index < 0)
            {
                throw new Exception("索引超出范围");
            }
            if (!Name[Index].Equals(Value))
            {
                throw new Exception(string.Format("索引{0}不存在{1}值",Value,Index));
            }
            for (int i = Index; i <Size-1; i++)//直接进行覆盖值操作
            {
                Name[i] = Name[i+1];
                if (i+1 == Size-1)
                {
                    Name[i + 1] = default(T);//最后一项清零
                }
            }
            last--;
        }

    }

下面让我们验证一下:

 //顺序表
            SeqList<string> a = new SeqList<string>(5);
            Console.WriteLine("-------------------进行赋值操作-----------------------");
            for (int i = 0; i < 5; i++)
            {
                a.Add(i.ToString());
            }
            Console.WriteLine("-------------------重新输出一遍-----------------------");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("索引值{0}处的值为{1}",i,a.GetVaule(i));
            }
            Console.WriteLine("-------------------进行删值操作-----------------------");
            a.Delete("2", 2);
            Console.WriteLine("-------------------重新输出一遍-----------------------");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("索引值{0}处的值为{1}", i, a.GetVaule(i));
            }
            Console.WriteLine("-------------------进行插值操作-----------------------");
            a.Insert("100", 3);
            Console.WriteLine("-------------------重新输出一遍-----------------------");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("索引值{0}处的值为{1}", i, a.GetVaule(i));
            }
            Console.WriteLine("-------------------进行寻值100操作--------------------");
            Console.WriteLine("该值的第一次出现的索引是{0}",a.Find("100"));
            Console.ReadKey();

运行结果:

C#数据结构学习:线性结构之顺序表
逻辑符合

注意:

本文只实现顺序表的删增改查功能,具体求表长,清空等功能请看这篇文章
https://www.jianshu.com/p/f6c415785ac9

总结:

在删值的时候没必要用default(T),直接往前移一位把前面的值覆盖就行了,但是要记得把最后一项清零,否则末尾数据会重复。
在移项的时候,往空出来的方向移,比如在删值操作,对于要移的项来说,前面有空位,所以是往前移;在插值操作,对于要移的项来说,后面有空位,所以是往后移,这点需要注意,不然会出现目标项后面的项值都是末尾数据。
跟链表相比,链表只需要修改链(下一个数据存储地址)和数据值即可,在进行删除插入的操作时候,不需要往前移或者往后移数据元素。

相关标签: 数据结构 c#