基于python的数据结构与算法------------------------------线性表

  • 一个线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系。是最基本的数据结构之一。
  • 将表中元素顺序地存放在一大块连续的存储区里,这样实现的表称为顺序表;将表元素存放在通过链接构造起来的一系列存储块里,这样实现的表称为链接表,简称链表。
  • 顺序表的实现:表中元素顺序存放在一片足够大的连续存储区里,首元素存入存储区的开始位置,其余元素依次顺序存放。元素之间的逻辑顺序关系通过元在存储区里的物理位置表示。
  • 元素存储区的大小决定了表的容量,这是分配存储块时确定的,对于这个元素存储区,容量值保持不变。而这个元素个数的记录要与表中实际元素个数保持一致,在表元素变化时,都需要更新这一记录。
  • python的list就是一种元素个数可变的线性表,可以加入和删除元素,在各种操作中维持已有元素的顺序。实现约束有:基于下标(位置)的高效元素访问和更新,时间复杂度应该是O(1);允许任意加入元素(不会出现由于表满而无法加入新元素的情况),而且在不断加入元素的过程中,表对象的标识不变。
  • list是一种采用分离式技术实现的动态顺序表。
  • 使用顺序表结构实现顺序表:最重要特点是O(1)时间的定位元素访问;最重要的麻烦事加入/删除等操作的效率问题。这类操作改变表中元素序列的结构,由于元素在顺序表的存储区里连续排列,加入/删除操作有可能要移动很多元素,操作代价高。只有特殊的尾端插入/删除操作具有O(1)时间复杂度。但插入操作复杂度还收到元素存储区固定大小的限制。通过适当的“加倍”存储区扩充策略,一系列尾端插入可以达到O(1)的平均复杂度。
  • 顺序表的优缺点都在于其元素存储的集中方式和连续性。从缺点看,这样的表结构不够灵活,不容易调整和变化。如果在一个表的使用中需要经常修改结构,用顺序表去实现就不太方便,反复操作的代价可能很高。
  • 还有如果需要巨大的线性表,采用顺序表实现就需要巨大块的连续存储空间,造成存储管理方面的困难。
  • 基于链接结构,用链接关系显示表示元素之间的顺序关联。基于链接技术实现的线性表称为链接表或者链表。
  • 采用链接方式实现线性表的基本想法如下:把表中的元素分别存储在一批独立的存储块(表的节点)里。保证从组成表结构中国的任一个节点可找到与其相关的下一个结点;在迁移结点里用链接的方式显示地记录与下一结点之间的关联。
  • 单链表
  • 为了掌握一个表,只需要用一个变量保存着这个表的首节点的引用,这个变量称为表头变量或表头指针。
  • 一个单链表有一些具体的表结点构成;每个结点是一个对象,有自己的标识,下面也常称其为该结点的链接;结点之间通过结点链接建立起单向的顺序联系。
  • 为了标识一个链表的结束,只需给表的最后结点的链接域设置一个不会作为结点对象标识的值(称为空链接),在python里自然用系统常量None表示这种情况。
  • 循环单链表,其中最后一个结点的next域不用None,而是指向表的第一个结点。
  • 基本单链表包含一系列结点,通过一个方向的链接构造起来。它支持高效的(O(1))首端插入和删除操作,定位操作或尾部操作都需要o(n)时间。
  • 增加了尾结点引用域的单链表可以很好地支持首端/尾端插入和首端弹出元素,都是o(1)时间复杂度的操作,但不能支持高效的尾端删除。
  • 循环单链表也能支持高效的表首端/尾端插入和首端弹出元素。在这种表上扫描,需要特别注意结束判断问题。
  • 双链表中每个结点都有两个方向的链接,因此可以高效地找到前后结点。如果有尾结点引用,两端插入和删除操作都能在o(1)时间完成。循环双链表的性质类似
  • 对于单链表,遍历和数据检索操作都只能从表头开始。,需要o(n)时间。对于双链表,这些操作可以从表头或表尾开始,复杂度不变。与它们对应的两种循环链表,遍历和检索可以从表中任何一个地方开始,但要注意结束条件。
  • 链表的优点:
  • 表结构是通过一些链接起来的节点形成的,结点(及其中表元素)之间的顺序由链接关系决定,链接可以修改,因此表的结构很容易调整和修改。
  • 不需要修改结点里的数据元素或移动它们,只通过修改结点之间的链接,就能灵活地修改表的结构和数据排列方式。
  • 整个表由一些小的存储块构成,比较容易安排和管理。
  • 链表的缺点:
  • 定位访问(基于位置找到元素)需要线性时间,这是与顺序表相比的最大劣势。
  • 简单单链表山的尾端操作需要线性时间。增加一个尾指针,可以将尾端插入变成常量时间操作,但仍不能有效实现尾端删除。双链表通过在每个结点里增加第二个链接,可以实现两端的高效插入和删除。
  • 要找当前元素的前一元素,必须从头开始扫描表结点。这种操作应尽量避免。双链表可以解决这个问题,但每个结点要付出更多存储代价。
  • 为存储一个表元素,需要多用一个连接域,这是实现链接表的存储代价。双链表可以提高链表操作的灵活性,但需要增肌啊两个链接域。

猜你喜欢

转载自blog.csdn.net/eason_oracle/article/details/80318729