【数据结构】线性表(六)堆栈:顺序栈及其基本操作(初始化、判空、判满、入栈、出栈、存取栈顶元素、清空栈)

文章目录

  • 一、堆栈
    • [1. 定义](#1. 定义)
    • [2. 基本操作](#2. 基本操作)
  • 二、顺序栈
    • [0. 顺序表](#0. 顺序表)
    • [1. 头文件和常量](#1. 头文件和常量)
    • [2. 栈结构体](#2. 栈结构体)
    • [3. 栈的初始化](#3. 栈的初始化)
    • [4. 判断栈是否为空](#4. 判断栈是否为空)
    • [5. 判断栈是否已满](#5. 判断栈是否已满)
    • [6. 入栈](#6. 入栈)
    • [7. 出栈](#7. 出栈)
    • [8. 查看栈顶元素](#8. 查看栈顶元素)
    • [9. 清空栈](#9. 清空栈)
    • [10. 主函数](#10. 主函数)
    • [11. 代码整合](#11. 代码整合)

堆栈Stack 和 队列Queue是两种非常重要的数据结构,两者都是特殊的线性表:

  • 对于堆栈,所有的插入和删除(以至几乎所有的存取)都是在表的同一端进行
  • 对于队列,所有的插入都是在表的一端进行,所有的删除(以至几乎所有的存取)都是在表的另一端进行。

一、堆栈

1. 定义

堆栈 (简称)是一种操作受限的线性表,只允许在表的同一端进行插入和删除操作,且这些操作是按后进先出的原则进行的。进行插入和删除的一端被称为栈顶,另一端被称为栈底。当栈中无元素时称其为空栈。根据上述定义,每次删除(退栈)的总是最后插入(进栈)的元素。

如图所示的堆栈中,诸元素以a1,a2,a3,a4,a5的顺序进栈,而退栈的次序则是a5,a4,a3,a2,a1。 也就是说,从栈中取走元素是按后进先出的原则进行的,因此栈又被称作后进先出 (Last in First Out)的线性表,简称为LIFO表

2. 基本操作

  • 堆栈是受限的线性表,其基本操作包括
    • push ( ) : 压入一个元素(插入);
    • pop ( ) : 弹出一个元素(删除);
    • peek ( ) : 存取栈顶元素值;
    • clear ( ) : 清空栈;
    • IsEmpty ( ) : 判断栈是否为空;
  • 同普通线性表一样,堆栈也可以用顺序存储和链接存储两种方式来实现:

二、顺序栈

用顺序存储方式实现的堆栈称为顺序栈

  • 顺序栈用数组存放栈元素,可方便地进行各种栈操作;
  • 某一堆栈的规模指该堆栈最多能容纳的元素个数;
  • 存放堆栈的数组规模(或大小)应按堆栈的规模来确定:
    • 当堆栈中元素的个数达到堆栈规模(简称为栈满)时,则无法再向堆栈插入元素,换言之此时的插入操作将产生上溢出。
  • 如何确保既不上溢也不下溢?
    • 需要一个整型变量size来存放数组规模,以及一个整型变量top来存放栈顶元素在数组中的位置(下标)
      • 当栈为空时,top值为0
      • 每入栈(或出栈)一个元素,top值加1(或减1)
      • 当top等于size时,说明栈满

0. 顺序表

参考前文:顺序表及其基本操作

1. 头文件和常量

c 复制代码
   #include <stdio.h>
   #include <stdlib.h>

   #define MAX_SIZE 100
  • 两个头文件
    • stdio.h用于输入输出操作
    • stdlib.h用于内存分配和释放
  • 通过#define指令定义了一个常量MAX_SIZE,它表示栈的最大容量为100

2. 栈结构体

c 复制代码
   typedef struct {
       int data[MAX_SIZE];
       int top;
   } Stack;

使用结构体定义了一个栈的数据结构,data是一个整型数组,用于存储栈中的元素,top表示栈顶的索引。

3. 栈的初始化

c 复制代码
   void init(Stack* stack) {
       stack->top = -1;
   }

初始化栈,将栈顶索引top置为-1,表示栈为空。

4. 判断栈是否为空

c 复制代码
   int isEmpty(Stack* stack) {
       return stack->top == -1;
   }

判断栈是否为空,如果栈顶索引top等于-1,表示栈为空,函数返回1;否则,返回0。

5. 判断栈是否已满

c 复制代码
   int isFull(Stack* stack) {
       return stack->top == MAX_SIZE - 1;
   }

isFull函数用于判断栈是否已满,如果栈顶索引top等于MAX_SIZE - 1,表示栈已满,函数返回1;否则,返回0。

6. 入栈

c 复制代码
   void push(Stack* stack, int value) {
       if (isFull(stack)) {
           printf("Stack is full. Cannot push element.\n");
           return;
       }
       stack->data[++stack->top] = value;
   }

push函数用于将元素入栈,首先判断栈是否已满,如果已满,则打印错误信息并返回;否则,将元素存储在栈顶索引top的位置,并将栈顶索引加1。

7. 出栈

c 复制代码
   int pop(Stack* stack) {
       if (isEmpty(stack)) {
           printf("Stack is empty. Cannot pop element.\n");
           return -1;
       }
       return stack->data[stack->top--];
   }

pop函数用于将栈顶元素出栈,首先判断栈是否为空,如果为空,则打印错误信息并返回-1;否则,返回栈顶元素的值,并将栈顶索引减1。

8. 查看栈顶元素

c 复制代码
   int peek(Stack* stack) {
       if (isEmpty(stack)) {
           printf("Stack is empty. Cannot peek element.\n");
           return -1;
       }
       return stack->data[stack->top];
   }

peek函数用于查看栈顶元素的值,首先判断栈是否为空,如果为空,则打印错误信息并返回-1;否则,返回栈顶元素的值。

9. 清空栈

c 复制代码
   void clear(Stack* stack) {
       stack->top = -1;
   }

clear函数用于清空栈,将栈顶索引top置为-1,表示栈为空。

10. 主函数

c 复制代码
int main() {
    Stack stack;
    init(&stack);

    push(&stack, 10);
    push(&stack, 20);
    push(&stack, 30);

    printf("Top element: %d\n", peek(&stack));

    printf("Popped element: %d\n", pop(&stack));
    printf("Popped element: %d\n", pop(&stack));

    printf("Is stack empty? %s\n", isEmpty(&stack) ? "Yes" : "No");

    clear(&stack);

    printf("Is stack empty? %s\n", isEmpty(&stack) ? "Yes" : "No");

    return 0;
}
  • 声明一个Stack类型的变量stack,然后调用init函数对栈进行初始化。

  • 使用push函数将元素10、20和30依次入栈。

  • 使用peek函数查看栈顶元素的值。

  • 使用pop函数将栈顶的两个元素出栈。

  • 使用isEmpty函数判断栈是否为空。

  • 调用clear函数清空栈。

  • 再次使用isEmpty函数判断栈是否为空。

11. 代码整合

c 复制代码
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int top;
} Stack;

void init(Stack* stack) {
    stack->top = -1;
}

int isEmpty(Stack* stack) {
    return stack->top == -1;
}

int isFull(Stack* stack) {
    return stack->top == MAX_SIZE - 1;
}

void push(Stack* stack, int value) {
    if (isFull(stack)) {
        printf("Stack is full. Cannot push element.\n");
        return;
    }
    stack->data[++stack->top] = value;
}

int pop(Stack* stack) {
    if (isEmpty(stack)) {
        printf("Stack is empty. Cannot pop element.\n");
        return -1;
    }
    return stack->data[stack->top--];
}

int peek(Stack* stack) {
    if (isEmpty(stack)) {
        printf("Stack is empty. Cannot peek element.\n");
        return -1;
    }
    return stack->data[stack->top];
}

void clear(Stack* stack) {
    stack->top = -1;
}

int main() {
    Stack stack;
    init(&stack);

    push(&stack, 10);
    push(&stack, 20);
    push(&stack, 30);

    printf("Top element: %d\n", peek(&stack));

    printf("Popped element: %d\n", pop(&stack));
    printf("Popped element: %d\n", pop(&stack));

    printf("Is stack empty? %s\n", isEmpty(&stack) ? "Yes" : "No");

    clear(&stack);

    printf("Is stack empty? %s\n", isEmpty(&stack) ? "Yes" : "No");

    return 0;
}
相关推荐
浅陌pa6 分钟前
01:(寄存器开发)点亮一个LED灯
c语言·stm32·单片机·嵌入式硬件
武昌库里写JAVA30 分钟前
Vue3常用API总结
数据结构·spring boot·算法·bootstrap·课程设计
卑微求AC32 分钟前
(C语言贪吃蛇)4.贪吃蛇地图优化及算法说明
c语言·算法
DdddJMs__1351 小时前
C语言 | Leetcode C语言题解之第458题可怜的小猪
c语言·leetcode·题解
凯子坚持 c2 小时前
C语言复习概要(四)
c语言·开发语言
轩辰~2 小时前
磁盘存储链式结构——B树与B+树
数据结构·b树·算法
小懒编程日记3 小时前
【数据结构与算法】B树
java·数据结构·b树·算法
Bruce_Li_Q4 小时前
C语言贪吃蛇
c语言·开发语言
马浩同学4 小时前
【ESP32】Arduino开发 | Timer定时器+定时器闹钟例程
c语言·单片机·嵌入式硬件·mcu
Beginner_bml4 小时前
C语言---链表
c语言·数据结构