线性表、栈和队列简记

2 篇文章 0 订阅
1 篇文章 0 订阅

线性表

分类

顺序表
  • 实现
    1. 一个分配固定长度的数组,两个int变量,分别是maxSize(数组总长度),listSize(已存在元素,数组实际长度)
  • 效率
    1. 对于insert和remove操作(头尾除外),平均来说,需要移动一半元素,故时间代价Φ(n);其他操作Φ(1),如访问元素
    2. 适合访问操作比修改操作多的场景、以及元素数量固定或大概估计出线性表长度的场景
    3. 比链表有更高的空间效率,因为没有指针这些结构性开销
  • 应用
    1. Java中把它实现成List接口,规范其具有的行为。最常用的就是实现了该接口的ArrayList类。
    2. ArrayList类有以下特点:
    • 私有属性主要是Object[]和size。Object[]的长度length(默认值为10)比size,因为size表示数组实际的大小。
    • 基于上面一点,与一般的顺序表相比,ArrayList具有扩容ensureCapacity()和缩容trimToSize()的行为
    • 扩容和缩容是开销很大的行为,在容量不足和容量过多的时候,都会执行数组拷贝,拷贝过程中使用函数arraycopy(Object src, int srcPos, Object dest, int destPos, int length),这是一个native方法,调用C/C++代码,效率很高,所以Java推荐在进行大量数组拷贝的时候使用该方法。
    • 所以在使用ArrayList时,建议在确定其大小的场景下使用,尽量避免频繁的扩容。
    • 增删和访问元素就不多说了,跟上面讲的顺序表的特性一样。顺便提一下ArrayList的边界检查和modCount属性。在add()和remove()等涉及越界访问数组元素的操作,会先调用rangeCheck()进行检查,超出则抛出异常IndexOutOfBoundsException;而modCount,是非线程安全的ArrayList为了避免线程的不确定性而引入Fail-Fast机制。Fail-Fast机制
链表
  • 实现
    1. 建立结点类和利用指针,结点类有个好处是能被栈和队列的连接实现方式重用
    2. 通过增加一个表头结点,避免当链表为空时处理的复杂性,初始状态下,head/curr/tail指针都指向表头结点。
  • 效率
    1. 对于访问操作,平均来说,只能从头遍历链表,时间代价Φ(n)
    2. 增删指针所指的结点,如栈和队列中经常发生,时间代价Φ(1)
    3. 但如果增删指定的元素,需要遍历找到该元素,时间代价为Φ(n)
  • 应用
    • 在Java中,最常用的是双向链表LinkedList,继承于AbstractSequentialList,实现 List 接口、Deque 接口。故也可以被当作堆栈、队列或双端队列进行操作
    • 数据结构是基于双向循环链表的,且头结点中不存放数据,链表空时,previous和next都指向header表头。(一般的单向链表previous和next为null)
    • 在LinkedList增删元素甚至扩容效率都很高,主要注意修改指针的先后。还有,由于是循环链表,插入位置如果是size,则在头结点前面插入。
    • 访问元素需要遍历,所以效率不高,Java使用”根据index的大小来决定开始遍历的一端(if (index < (size >> 1)) )“来提高效率。

—— 仅在一端进行插入或删除操作的线性表;元素写入和读出顺序相反,”LIFO”后进先出;单向延伸特性

分类

顺序栈
  1. 数组最后一个元素的位置作为栈顶(top),进行插入或删除操作,时间代价Φ(1)
  2. 固定长度,可能浪费空间
链式栈

只能在表头进行插入和删除,不需要空的表头节点

队列

—— 仅在从队尾插入,从队首删除元素的线性表;”FIFO”先进先出

分类

顺序队列(循环队列)
  1. 实现循环数组,首尾指针变量front/rear(int类型,记录数组索引),初始状态front=1,rear=0
  2. 通过对size求余%,达到循环遍历数组;front==rear时,认为队列只有一个元素
  3. 为区分队列是空还是满,选择大小为n+1的数组,只存储n个元素;front-rear=1时,表示队列空,front-rear=2时,表示队列满
链式队列

使用一个空的表头结点,初始化时,front和rear同时指向头结点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值