什么是线性结构?
线性结构时最常见,最普片的一种属觉结构,线性表是线性结构的一种抽象。线性结构的特点是,线性结构数据元素之间存在着一对一的关系,这种元素之间的关系是指他们的位置关系,而这种一对一之间的元素关系是指:(1)除第一个元素外,它的前面永远都只有一个元素,(2)除最后一个元素外,他的前面永远只有一个元素。也就是说线性结构是数据一个挨着一个排列的。
在C#中常用的线性结构比较?
《1》先来说说内存连续的线性结构
在C# 中,我们通常要存储一组数据,我们通常会想到: 数组,ArrayList,List这三个线性对象,而它们之间有什么区别呢?我们先来说说数组。
数组由许多优点,比如说他内存是连续存储的,当我们修改值,索引值的时候非常方便,而且也非常的快,不用整个去遍历,直接拿到内存进行读取修改。
string[] s=new string[3];
//赋值
s[0]="a";
s[1]="b";
s[2]="c";
//修改
s[1]="b1";
凡事有利也有弊,数组这样读区到是方便很多,但是当插入,创建的时候就非常的棘手和麻烦了,当创建的时候,必须要主动的给数组对象分配一定的空间来存储,当你分配过大会浪费空间,当你分配的过小,那么数组会溢出,当你添加一个新的元素在指定两个元素之间的时候,我们需要把后边的元素进行位置移动,然后空出的位置在插入新的元素。为了解决这个问题,我们推出了新的数据结构ArrayList,我们先来上一个例子:
ArrayList list = new ArrayList();
//新增数据
list.Add("abc");
list.Add(123);
//修改数据
list[2] = 345;
//移除数据
list.RemoveAt(0);
//插入数据
list.Insert(0, "hello world");从上面的例子我们可以看出,同一个Arraylist 不仅可以插入“abc” string类型,同时也可以插入123 int类型,这样可以得知ArrayList插入不同的数据类型是可以的,同样可以推理出,它数据的插入和读取是经过“装箱”和“拆箱”的过程的,是不安全的数据类型,而拆箱装箱的过程是非常影响性能的,而且它把插入的数据都当作了object来处理,
既使我们保证在插入数据的时候都很小心,都有插入了同一类型的数据,但在使用的时候,我们也需要将它们转化为对应的原类型来处理。
之所以ArrayList不是数据安全的,并且数据的操作需要装箱,拆箱这一严重缺点,所以C# 2.0 之后又相继推出了范型接口List,他基本上是ArrayList的等效类,操作也基本上相似,唯一不一样的地方是,在创建的时候他需要制定特定的数据类型。
List<int> list = new List<int>();
//新增数据
list.Add(123);
//修改数据
list[0] = 345;
//移除数据
list.RemoveAt(0);
这样,如果我们插入”abc“,在编译的时候就会报错,这样就有效的避免了装箱拆箱的过程,他融合了Array快速访问,和ArrayList长度可以灵活变化的优点
《2》内存不一定连续,但是逻辑上连续的线性结构
LinkedList<T> 链表:和上述集合最大的区别就是它在内存上可以不是连续的,那么它对比集合最大的优点也就很清楚了。
(1)向容器中添加或者删除元素,无需调整容器的容量,因为它内存上不是连续存储的, 他是靠元素的指针来决定的。所以频繁删除和增加元素它比较有优势。
(2)链表适合在需要有序的情况下添加删除元素,他和数组比较,数组添加或者删除元素的时候,他需要把现有的元素进行存储位置的变更,而链表周要改变相邻两个元素指针的指向就OK了。
(3)他有优点也就有缺,他由于内存上排列不是连续的,所以就不能像数组一样,利用下标来进行直接访问,他需要对整个链表进行编译,来进行对值做比较。这一点远远不能和数组相比。
Queue<T> 队列:在这种线性结构中,最先被插入的数据是最先被删除,反之最后插入的数据则最后被删除,因此,他是一种先进先出的线性表结构对象。因此我们在使用他需要注意几点:
(1)先进先出的特性。
(2)在默认情况下,Queue<T>的容量为32,增长因子为2
(3)当Enqueue时,会先判断他的容积是不是够用,不够用的时候,他会根据增长因子来扩充自己的容器。
Stack<T> 堆栈:这个是和Queue<T>相反的一个容器,他当然是先先进后出的,同时需要注意的就是它的默认容器为10,使用Pop和push来进行操作。
结束:
常用的线性结构就基本上写完了,在实际的编程过程中,你面对一些问题的时候,就可以根据数据的操作取向来进行选择相应的数据结构,这样就能够扬长避短。