线性表的概念

一.定义

线性表是最简单也是编程中使用最多的一种数据结构。

例如英文字母表,成绩单 线性表(Linear List)是具有相同特性的数据元素的一个有限序列,是对线性结构的抽象 。

线性结构的特点是结构中的数据元素在位置上有序,并且元素之间存在一对一的线性关系。

(1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素;

(2)除最后一个位置的数据元素外,其它数据元素位置的后面都只有一个元素。 也就是说,数据元素是一个接一个的排列。

线性表就是位置有先后关系,一个接着一个排列的数据结构。

二.分类

1.顺序表存储

线性表的顺序存储结构。

用一块连续的存储空间一次存储线性表中的数据元素。

这种存储方式,好比改革前的银行,办理业务需要排队才能办理。

他们在逻辑上相邻,物理上也相邻。

C#中给我们提供的线性表有很多,我们先知讨论基础常用的 Array  ArrayList  List<T>

1.1数组

 int[] arrInt = new int[5];
 arrInt[2] = 5;
 arrInt[4] = 3;

访问数据速度快,如果第一个元素位置为Loc,存储空间 为n,那么第i个元素的存储地址为: Loc+(i-1)*n

访问元素的时间复杂度为O(1)

1.2 ArrayList

数组有很多优点,但是缺点也非常明显,在实际编程中,经常需要对集合中元素进行添加和删除,也需要动态改变集合的大小,数组显然无法满足这种需求。

我们来介绍基于数组的另外一个顺序表ArrayList。

Add() //添加元素
Insert() //在指定索引出插入元素
RemoveAt() //删除指定索引的元素
TrimToSize() //裁剪空间,使存储空间正好适合元素个数
this[int index]  索引器,通过索引获取和设置元素
Count:获取当前元素的个数
Capacity:占用的存储空间

1.3 List<T>

ArrayList 使用object数组,所有会有一些装箱拆箱的消耗。 List<T> 使用了泛型,类型安全,比ArrayList 性能更优。

在实际编程中,建议使用List<T>代替ArrayList.

List<T>的使用和原理,我们这里不再多提了, 把这部分实现放在C# 讲泛型的时候, 原理跟ArrayList是一样的。

2.链表存储

链表是怎么表示两个数据元素逻辑上的相邻关系呢?

如何表示数据元素之间的线性关系呢?

在存储数据元素时,除了存储数据元素本身的信息外,还有一个指针,指向他的后继节点。

节点数据示意图:

链表示意图:

2.1单链表

单链表对于元素的插入和删除操作非常方便,不像顺序表那样需要移动元素。

但是元素的定位问题导致效率的下降,特别是单向链表数据增多的时候更为明显。

C# 只有一个类是单向链表 System.Collections.Specialized.ListDictionary 是基于键/值对(key/value)的集合。

微软建议:包含10个或者以下的集合,可以考虑使用。

优化:单链表里加入一个尾指针(tail),提高添加元素的性能。

面试 顺序表:存取数据快 链表:插入删除数据快

2.2双向链表

单向链表访问后继节点很方便,时间复杂度为O(1)。

但是访问前驱节点,必须从头指针开始遍历,找到一个节点的next为该节点,就是前驱节点。

因为单链表的只有一个指向后继节点的next,只能顺着一个方向寻找。 所以你如果想很方便的找到前驱节点,可以在加一个指向前驱节点的指针prev,使链表可以双向查找,这种数据结构成为双链表。

①双向链表的插入:双向链表的插入需要经过4次指针的操作,需要注意指针操作的顺序。如果当前节点为p,在p后面插入s节点的算法如下:

s.prev = p;
s.next = p.next;
p.next.prev = s;
p.next = s;

②双向链表删除:双向链表的删除需要经过2次指针的操作,删除s节点的算法如下:

s.prev.next = s.next;
s.next.prev = s.prev;

2.3循环链表

循环链表是另一种形式的链式存储结构。

在单向链表中,每个节点的指针都指向其下一个节点,最后一个节点的指针为空,表示链表结束。我们修改下数据结构,将链表最后一个节点的指针指向第一个节点,这样就形成了一个环,这种数据结构叫做单向循环列表.另外还有双向循环列表(略)。 

循环链表结构中从表的任一节点出发均可以找到表中的其他节点 如果从表头节点出发,访问链表的最后一个节点,必须扫描表中 所有节点。若循环链表的头指针改用尾指针代替,则从尾指针出发 不仅可以立即访问到最后一个节点,而且十分方便的找到第一个节点。

三.线性表总结

1.示意图

2.线性表之顺序表

优点:

1.算法简单,描述逻辑关系不额外增加内存     2.索引访问数据性能更优

缺点:    

1.空间需要手动分配,不足,溢出;反之,空间闲置而浪费。

2.动态数组解决了空间固定问题,但是空间浪费,频繁添加操作,会导致空间不断重新分配,影响性能。     

3.删除和插入操作笨拙不便,常常导致数据大范围移动,影响算法速度。

3.线性表之链表

优点:

1.需要空间就申请,不需要就释放,空间有效利用。     

2.删除和插入只需要修改几个指针即可,方便快捷。     

3.双向链表双向搜索,简化算法的复杂度。

缺点:

1.算法实现复杂抽象,需要额外内存空间保存节点的逻辑关系。     

2.只能顺序访问,随机访问性能不佳。     

3.可能会把节点存放到托管堆的任意角落,垃圾回收需要更多开销。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值