程序员“修炼成神”的必经之路——数据结构(第3章 栈和队列)

Posted 猿力满满

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序员“修炼成神”的必经之路——数据结构(第3章 栈和队列)相关的知识,希望对你有一定的参考价值。

目录

前言

一、栈

1.栈的定义及其运算

    1)栈的定义

    2)栈的运算

2.栈的存储表示

    1)栈的顺序存储结构

    2)栈的链式存储结构

二、队列

1.队列的定义及其运算

    1)队列的定义

    2)队列的运算

2.顺序循环队列

3.链队列

小结


前言

       本篇文章给小伙伴们分享数据结构的第3章——栈和队列,本文主要介绍栈和队列的基本概念,不会涉及复杂的算法和代码。栈和队列是非常重要的两种线性结构,应用也非常广,所以建议小伙伴们最好要掌握这部分内容。


一、栈

1.栈的定义及其运算

    1)栈的定义

       栈是限定在表的一端进行插入和删除运算的线性表,通常将插入、删除的一端称为栈顶(top),另一端称为栈底(bottom)。

       根据栈的上述定义,栈的元素只能按照后进先出的原则修改。因此,栈又称为后进先出的线性表,简称LIFO表。

    2)栈的运算

    栈的运算主要有以下几种:

  1. 置空栈 InitStack(&S):构造一个空栈S。
  2. 判栈空 StackEmpty(S):若栈S为空栈,则返回TRUE,否则返回FALSE。
  3. 判栈满 StackFull(S):若栈S为满栈,则返回TRUE,否则返回FALSE。
  4. 进栈(又称入栈或插入)Push(&S,x):将元素 x 插入S栈的栈顶。
  5. 退栈(又称出栈或删除)Pop(&S):若栈S为非空,则将S的栈顶元素删除,并返回栈顶元素。
  6. 取栈顶元素 GetTop(S):若S栈为非空,则返回栈顶元素,但不改变栈的状态。

2.栈的存储表示

    1)栈的顺序存储结构

       栈的顺序存储结构称为顺序栈。由于栈是运算受限的线性表,因此线性表的存储结构对栈也适用。类似于顺序表的定义,顺序栈也是用数组实现的。因为栈底位置是固定不变的,故可以将栈底位置设置在数组的最低端(即下标为0);栈顶位置是随着进栈和退栈操作而变化的,故需用一个栈顶指针top来指示当前栈顶位置。

       由于顺序栈必须预先分配存储空间,因此可能会产生溢出和空间浪费的问题。为解决这个问题,我们可以让多个栈共享存储空间,这样可以相互调节,既节约了空间,又可以降低发生溢出的频率。

       怎样使多个栈共享存储空间呢?当程序中同时使用两个栈时,可以将两个栈的栈底分别设在顺序存储空间两端,让两个栈顶各自向中间延伸。当一个栈中元素较多进而使用空间超过共享空间一半时,只要另一个栈元素不多,就可以占用另一个栈的部分存储空间。只有当整个共享空间被两个栈占满时(即两栈顶相遇),才会产生溢出。

    2)栈的链式存储结构

       栈的链式存储结构称为链栈,它是运算受限的单链表,其插入和删除操作仅限制在表头位置上(栈顶)进行,因此不必设置头结点,将单链表的头指针head改为栈顶指针top即可。


二、队列

1.队列的定义及其运算

    1)队列的定义

       队列也是一种操作受限的线性表,它只允许在表的一端进行元素插入,而在另一端进行元素删除。允许插入的一端称为队尾(rear),允许删除的一端称为队头(front)。

       在队列中,通常元素插入称为入队,元素删除称为出队。队列的概念与现实生活中的排队相似,新来的成员总是加入队尾,排在队列最前面的总是最先离开队列,即先进先出,因此又称队列为先进先出(FIFO)表。

    2)队列的运算

    队列的操作运算与栈类似,主要有以下几种:

  1. 置空队列 InitQueue(Q),构造一个空队列Q。
  2. 判队空 QueueEmpty(Q),若Q为空队列,则返回TRUE,否则返回FALSE。
  3. 入队列 EnQueue(Q, x),若队列不满,则将数据 x 插入到Q的队尾。
  4. 出队列 DeQueue(Q),若队列不空,则删除队头元素,并返回该元素。
  5. 取队头 GetFront(Q),若队列不空,则返回队头元素。

2.顺序循环队列

       队列的顺序存储结构称为顺序队列。它也是利用一块连续的存储单元存放队列中的元素。由于队头和队尾位置是变化的,因此需要设置两个指针 front 和 rear 分别指示队头和队尾元素在表中的位置。

       为了充分利用数组空间,克服上溢,可将数组空间想象为一个环状空间,并称这种环状数组表示的队列循环队列。循环队列中,出队元素的空间可以重新被利用。所以,一般情况下真正实用的顺序队列是循环队列。

       判断循环队列是“空”还是“满”,常用方法一般有三种:

  • 另设一个标志位,以区别队列是“空”还是“满”。
  • 设置一个计数器记录队列中元素个数。
  • 少用一个元素空间,约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队列满,即尾指针Q.rear所指向的单元始终为空。

3.链队列

       队列的链式存储结构称为链队列。它是一种限制在表头删除和表尾插入操作的单链表。显然,仅有单链表的头指针不便在表尾作插入操作,为此再增加一个尾指针,使其指向链表上的最后一个结点。一个链队列由一个头指针和一个尾指针唯一确定


小结

       栈和队列是两种十分重要的线性结构,它们的逻辑结构和前面介绍的线性表完全相同,只是对其操作运算有一定的限制,故又称它们为操作受限的线性表。栈和队列结构在各种程序设计中被广泛应用。

ps:博主创作不易,喜欢这篇文章的老铁们点个赞吧!(#^.^#)

以上是关于程序员“修炼成神”的必经之路——数据结构(第3章 栈和队列)的主要内容,如果未能解决你的问题,请参考以下文章

程序员“修炼成神”的必经之路——数据结构(第2章 线性表)

程序员“修炼成神”的必经之路——数据结构(第4章 多维数组和广义表)

[架构之路-21]:目标系统 - 系统软件 - 计算机系统架构计算机指令系统结构化程序与分层编程。

[架构之路-23]:目标系统 - 系统软件 - C语言的结构与程序的工作原理 - 数据类型与数据定义(待续)

[架构之路-24]:目标系统 - 系统软件 - C语言的结构与程序的工作原理 - 程序控制函数调用栈函数调用性能优化

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型