【数据结构】 栈和队列

在计算机科学的世界里,数据结构是构建高效算法的基础。栈(Stack)和队列(Queue)作为两种基本且重要的数据结构,在软件开发、算法设计等众多领域都有着广泛的应用。今天,我们就来深入探讨一下栈和队列的奥秘。

1.栈(后进先出)

1.1栈的基本概念和结构

栈是一种遵循后进先出(Last In First Out,LIFO)原则的数据结构。想象一下一摞盘子,你只能从最上面拿走盘子,也只能把新盘子放在最上面。栈就类似这摞盘子,最后放入栈中的元素会最先被取出。

1.2栈的操作

  • 入栈(Push):将一个元素添加到栈的顶部。这就好比在一摞盘子的最上面再放一个盘子。
  • 出栈(Pop):移除并返回栈顶部的元素。相当于从一摞盘子中拿走最上面的那个盘子。
  • 查看栈顶元素(Peek):返回栈顶部的元素,但不移除它。
  • 判断栈是否为空(isEmpty):检查栈中是否有元素。

1.3栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些,因为数组在尾上插入数据的代价比较小。

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

#define MAX_SIZE 100

// 定义栈结构体
typedef struct {
    int items[MAX_SIZE];
    int top;
} Stack;

// 初始化栈
void initStack(Stack* s) {
    s->top = -1;
}

// 判断栈是否为空
int isEmpty(Stack* s) {
    return s->top == -1;
}

// 判断栈是否已满
int isFull(Stack* s) {
    return s->top == MAX_SIZE - 1;
}

// 入栈操作
void push(Stack* s, int item) {
    if (isFull(s)) {
        printf("栈已满,无法入栈!\n");
        return;
    }
    s->items[++(s->top)] = item;
}

// 出栈操作
int pop(Stack* s) {
    if (isEmpty(s)) {
        printf("栈为空,无法出栈!\n");
        return -1;
    }
    return s->items[(s->top)--];
}

// 查看栈顶元素
int peek(Stack* s) {
    if (isEmpty(s)) {
        printf("栈为空,无栈顶元素!\n");
        return -1;
    }
    return s->items[s->top];
}

int main() {
    Stack s;
    initStack(&s);

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

    printf("栈顶元素: %d\n", peek(&s));
    printf("出栈元素: %d\n", pop(&s));
    printf("出栈后栈顶元素: %d\n", peek(&s));

    return 0;
}
  1. 栈结构体 :定义了一个包含数组 items 和栈顶指针 top 的结构体 Stack
  2. 初始化栈initStack 函数将栈顶指针初始化为 -1,表示栈为空。
  3. 判断栈状态isEmpty 函数判断栈是否为空,isFull 函数判断栈是否已满。
  4. 入栈操作push 函数在栈未满时将元素添加到栈顶。
  5. 出栈操作pop 函数在栈不为空时移除并返回栈顶元素。
  6. 查看栈顶元素peek 函数在栈不为空时返回栈顶元素。

2.队列(先进后出)

2.1队列的概念和结构

2.2队列的操作

  • 入队(Enqueue):将一个元素添加到队列的尾部。类似于在排队的末尾加入一个人。
  • 出队(Dequeue):移除并返回队列头部的元素。就像排队的第一个人买到票后离开队伍。
  • 查看队头元素(Peek):返回队列头部的元素,但不移除它。
  • 判断队列是否为空(isEmpty):检查队列中是否有元素。

2.3队列的实现

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

#define MAX_SIZE 100

// 定义队列结构体
typedef struct {
    int items[MAX_SIZE];
    int front;
    int rear;
} Queue;

// 初始化队列
void initQueue(Queue *q) {
    q->front = 0;
    q->rear = -1;
}

// 判断队列是否为空
int isEmptyQueue(Queue *q) {
    return q->rear < q->front;
}

// 判断队列是否已满
int isFullQueue(Queue *q) {
    return q->rear == MAX_SIZE - 1;
}

// 入队操作
void enqueue(Queue *q, int item) {
    if (isFullQueue(q)) {
        printf("队列已满,无法入队!\n");
        return;
    }
    q->items[++(q->rear)] = item;
}

// 出队操作
int dequeue(Queue *q) {
    if (isEmptyQueue(q)) {
        printf("队列为空,无法出队!\n");
        return -1;
    }
    return q->items[(q->front)++];
}

// 查看队头元素
int peekQueue(Queue *q) {
    if (isEmptyQueue(q)) {
        printf("队列为空,无队头元素!\n");
        return -1;
    }
    return q->items[q->front];
}

int main() {
    Queue q;
    initQueue(&q);

    enqueue(&q, 10);
    enqueue(&q, 20);
    enqueue(&q, 30);

    printf("队头元素: %d\n", peekQueue(&q));
    printf("出队元素: %d\n", dequeue(&q));
    printf("出队后队头元素: %d\n", peekQueue(&q));

    return 0;
}
  1. 队列结构体 :定义了一个包含数组 items、队头指针 front 和队尾指针 rear 的结构体 Queue
  2. 初始化队列initQueue 函数将队头指针初始化为 0,队尾指针初始化为 -1。
  3. 判断队列状态isEmptyQueue 函数判断队列是否为空,isFullQueue 函数判断队列是否已满。
  4. 入队操作enqueue 函数在队列未满时将元素添加到队尾。
  5. 出队操作dequeue 函数在队列不为空时移除并返回队头元素。
  6. 查看队头元素peekQueue 函数在队列不为空时返回队头元素。
相关推荐
张小姐的猫20 分钟前
【AI大模型接入SDK】 —— 数据管理 & 与Session模块进行联动
数据结构·数据库·c++·人工智能·python·chatgpt
careathers1 小时前
【数据结构】栈
java·数据结构
mmmmath_32 小时前
LeetCode.018.四数之和
数据结构·算法·leetcode
淡海水2 小时前
11-02-Unity-Mono-vs-IL2CPP-两种脚本后端的数据结构行为差异
数据结构·unity·游戏引擎·il2cpp·mono
梦帮科技3 小时前
Next.js 16 模块化单体实战:App Router、领域模块与 Route Handler 分层
css·数据结构·链表·正则表达式·node.js·json·html5
雨落在了我的手上3 小时前
Java数据结构(十三):排序
数据结构
Logic1014 小时前
C语言/数据结构位运算题解:异或XOR找出独特卡片数字——只出现一次的元素
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
郝学胜-神的一滴4 小时前
C++20模板元编程 02:吃透模板基础核心四大核心知识点
开发语言·数据结构·c++·程序人生·软件工程·visual studio
我不会起名字3225 小时前
万字总结Golang入门项目
数据结构·经验分享·算法·golang·项目实战·复盘
不会就选b15 小时前
数据结构之排序
数据结构