表、栈、队列、向量及其ADT

表 List

基本概念

根据线性表的存储结构,可以分为以下两种:

  • 顺序表 (顺序存储)
    顺序表就是把线性表中所有的元素按照其逻辑顺序,依次存储到从指定的存储位置开始的一块连续的存储空间,这样线性表的第一个元素的存储位置就是指定的存储位置,第i+1个的存储位置紧跟着第i个元素的位置

  • 链表(链式存储)
    在链表存储中,每个结点不仅包含所存元素的信息,还包含元素之间的逻辑关系的信息,如单链表中前驱结点包含后继结点的地址信息,这样就可以通过前驱结点的位置找到后继结点的位置

两种存储结构的比较:
顺序表

  • 随机访问特性,位置是确定的
  • 要求占用连续的存储空间,存储分配只能预先进行,即静态分配
  • 插入操作要移动多个元素

链表

  • 不支持随机访问
  • 结点中的存储精简利用率稍低一些
  • 支持存储空间的动态分配
  • 插入操作无需移动元素

链表 Linked List

概念:
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

链表百科

单链表

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

带头结点的单链表
头指针head 指向头结点,头指针值域不包含任何信息,从头结点的后继结点开始存储信息,头指针始终不为null,当head->next 等于NULL的时候,链表为空

不带头结点的单链表
头指针head直接指向开始结点,当head为NULL的时候,链表为空

注意:不论是带有节点的链表还是不带头结点的链表。头指针都指向链表中的第一个结点,;而头结点是带头结点的链表中的第一个结点,只作为链表存在的标志

双链表

双链表就是在单链表的结点上增添一个指针域,指向当前结点的前驱;
同样 双链表也分为带头结点的双链表和不带头结点的双链表

循环链表

循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

循环单链表
将单链表的最后一个指针域指向链表中的第一个结点即可

循环双链表
循环双链表的构造源自双链表,即将终端结点的next指针指向链表中第一个结点,将链表中第一个结点的prior指针指向终端结点。

空链判断:
带头结点的循环双链表当head->next和heaad->prior两个指针都等于head时链表为空。
不带头结点的循环双链表当head等于null的时候为空。

静态链表

静态链表借助一位数组来表示,结构体数组中的每一个结点含有两个分量:一个是数据结构元素分量data,另一个是指针分量,指示了当前结点的直接后继结点在数组中的位置

表操作

对表的操作主要分为增加和删除节点,根据链表的特性,增加和删除时的细节不太一样,需要理解。暂时没有细说。

栈 Stack

基本概念

  • 栈是一种限制插入和删除操作只能在一个位置上进行的线性表。其中允许进行插入或者删除操作的一端称为栈顶(TOP)。栈顶由一个称谓栈顶指针的位置指示器(其实就是一个变量)。对于顺序栈,就是记录栈顶元素所在数组位置标号的一个整形变量;对于链式栈就是记录栈顶元素所在的结点地址的指针。另一端被称为栈底,栈底是固定不变的。
  • 栈的特点,先进后出(FILO)
  • 栈的存储结构,可用顺序表和链表来存储栈,分为顺序栈链式栈。 即栈的本质上是线性表
  • 当n各元素以某种顺序进栈,并且可以在任意时刻出栈,所获得的元素排列的数目N满足函数
    N=1/(n+1)Cn2n
  • 栈通常包括的三种操作:push、peek、pop。
    push – 向栈中添加元素。
    peek – 返回栈顶元素。
    pop – 返回并删除栈顶元素的操作。

栈的实现

由于栈是一个表,因此任何实现表的方法都能实现栈。一般有两种流行的实现方法,一种方法使用链式结构,另一种方法使用数组。
使用Java语言,可以简化ArrayList 和LinkedList的实现来做。

顺序栈

栈的数组实现。

顺序栈的特殊状态和操作

  • 栈空状态
    st.top==-1 有的书上规定st.top ==0为栈空条件
  • 栈满状态
    st.top==maxSize-1 maxSize为栈中最大元素的个数,则maxSize-1 为栈满时栈顶元素在树组中的位置
  • 非法状态(上溢和下溢)栈满继续进入栈就会出现上溢状态,栈空继续出栈就会出现下溢状态
  • 进栈操作
  • 出栈操作

链栈

链栈的特殊状态和操作

  • 栈空状态 lst->next==NULL
  • 栈满状态 不存在栈满的情况
  • 元素进栈操作
  • 元素出栈操作

队列 Queue

基本概念

  • 队列也是一种受限制的线性表,其显示为仅允许在表的一端进行插入,在表的另一端进行删除
  • 队列的基本操作:入队(enqueue),它是在表的末端(队尾 rear)插入一个元素;出队(dequeue),它是删除在表的开头(队头 front)的元素。
  • 队列的特点,先进先出(FIFO)
  • 可用顺序表和链表来存储队列,队列按存储结构可分为顺序队链队两种

队的实现

顺序队

主要介绍循环队列,之要front或rear到达数组的尾端,它就又绕到开头。
重点是仔细理解非循环队列出现问题的情况。

链队

向量 Vector

向量是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。

  1. 顺序序列
    顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。
  2. 动态数组
    支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。操供了在序列末尾相对快速地添加/删除元素的操作。
  3. 能够感知内存分配器的(Allocator-aware)
    容器使用一个内存分配器对象来动态地处理它的存储需求。

Vector的扩充机制:
按照容器现在容量的一倍进行增长。vector容器分配的是一块连续的内存空间,每次容器的增长,并不是在原有连续的内存空间后再进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个复制过去,然后销毁旧的内存。这时原有指向旧内存空间的迭代器已经失效,所以当操作容器时,迭代器要及时更新。

抽象数据类型 ADT

ADT:Abstract Data Type 抽象数据类型
是带有一组操作的一些对象的集合。

表 ADT

栈 ADT

队列 ADT

参考资料

https://blog.8hfq.com/2018/08/21/Data_structure_and_algorithm.html

今天先写了大概结构,具体内容,后期会再添加!

发布了79 篇原创文章 · 获赞 10 · 访问量 8695

猜你喜欢

转载自blog.csdn.net/weixin_44728363/article/details/98471384