【数据结构实战】C 语言实现静态顺序队列:从原理到完整可运行代码

1. 队列的顺序结构定义(静态数组版)
cpp 复制代码
#define MAXSIZE 100  // 队列最大容量
typedef int ElemType; // 队列元素类型,这里用int举例

// 顺序队列结构体定义
typedef struct {
    ElemType data[MAXSIZE]; // 存储队列元素的数组
    int front;              // 队头指针,指向队头元素
    int rear;               // 队尾指针,指向队尾元素的下一个位置
} Queue;

注释说明

  • MAXSIZE 限定队列最多能存的元素个数。
  • front 初始为 0,代表队头位置;rear 初始为 0,代表下一个入队元素要存放的位置。
  • front == rear 时队列为空。

2. 队列初始化
cpp 复制代码
// 初始化队列:将队头和队尾指针置为0
void initQueue(Queue *Q) {
    Q->front = 0; // 队头指针指向0
    Q->rear = 0;  // 队尾指针指向0
}

注释说明

  • 初始化后队列状态为空(front == rear)。
  • 传入指针是为了直接修改原队列结构体。

3. 判断队列是否为空
cpp 复制代码
// 判断队列是否为空:空返回1,非空返回0
int isEmpty(Queue *Q) {
    if (Q->front == Q->rear) { // 队头等于队尾,说明无元素
        printf("空的\n");
        return 1;
    } else {
        return 0;
    }
}

注释说明

  • 核心判断条件:front == rear 表示队列中没有元素。
  • 空队列时打印提示并返回 1,否则返回 0。

4. 入队操作(静态数组版)
cpp 复制代码
// 入队:将元素e插入队尾,成功返回1,失败返回0
int enqueue(Queue *Q, ElemType e) {
    if (Q->rear >= MAXSIZE) { // 队尾指针超出数组最大下标,队列满
        if (!queueFull(Q)) {  // 调用队列满处理函数(后续实现)
            return 0;
        }
    }
    Q->data[Q->rear] = e; // 将元素e存入队尾位置
    Q->rear++;            // 队尾指针后移
    return 1;             // 入队成功
}

注释说明

  • 先检查队尾是否越界(rear >= MAXSIZE),若越界则尝试处理队列满。
  • 未越界时,将元素存入data[rear],并让rear自增。
  • 成功入队返回 1,失败返回 0。

5. 出队操作
cpp 复制代码
// 出队:删除队头元素并返回,空队列返回0
ElemType dequeue(Queue *Q) {
    if (Q->front == Q->rear) { // 队列为空,无法出队
        printf("空的\n");
        return 0;
    }
    ElemType e = Q->data[Q->front]; // 取出队头元素
    Q->front++;                    // 队头指针后移
    return e;                      // 返回出队元素
}

注释说明

  • 先判断队列是否为空,为空则打印提示并返回 0。
  • 非空时,取出data[front]的值,让front自增,实现 "删除队头"。
  • 返回被出队的元素值。

6. 获取队头元素(不删除)
cpp 复制代码
// 获取队头元素:将队头元素存入*e,成功返回1,失败返回0
int getHead(Queue *Q, ElemType *e) {
    if (Q->front == Q->rear) { // 队列为空,无队头元素
        printf("空的\n");
        return 0;
    }
    *e = Q->data[Q->front]; // 将队头元素赋值给*e
    return 1;               // 获取成功
}

注释说明

  • 与出队不同,getHead 只读取data[front],不修改front指针。
  • 通过指针e带回队头元素值,避免函数返回值同时承载 "状态 + 数据" 的歧义。

7. 队列满处理(数据搬移)
cpp 复制代码
// 处理队列满:将有效数据搬移到数组开头,释放后面空间
int queueFull(Queue *Q) {
    if (Q->front > 0) { // 队头不在0位置,说明前面有空闲空间
        int step = Q->front; // 计算需要前移的步数
        // 遍历有效数据,将其向前移动step位
        for (int i = Q->front; i < Q->rear; ++i) {
            Q->data[i - step] = Q->data[i];
        }
        Q->front = 0;                // 队头重置为0
        Q->rear = Q->rear - step;    // 队尾同步前移
        return 1;                    // 处理成功
    } else {
        printf("真的满了\n"); // 队头已经是0,无空闲空间,队列真满
        return 0;
    }
}

注释说明

  • 静态数组队列会出现 "假溢出"(rear到末尾但front前有空位),此函数解决该问题。
  • [front, rear-1]的有效数据搬移到[0, rear-front-1],重置frontrear
  • front已经是 0,说明队列真满,无法处理。

8. 动态内存分配版队列定义
cpp 复制代码
// 动态分配版队列结构体
typedef struct {
    ElemType *data; // 指向动态分配的数组指针
    int front;       // 队头指针
    int rear;        // 队尾指针
} Queue;

// 动态初始化队列:返回队列指针
Queue* initQueue() {
    // 为队列结构体分配内存
    Queue *q = (Queue*)malloc(sizeof(Queue));
    // 为数据数组分配MAXSIZE个元素的内存
    q->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
    q->front = 0; // 初始化队头
    q->rear = 0;  // 初始化队尾
    return q;      // 返回队列指针
}

注释说明

  • malloc动态分配数组空间,相比静态数组更灵活(可在运行时决定容量)。
  • initQueue 封装了队列创建和初始化的全过程,返回一个可用的队列指针。

二、完整可运行代码(含注释)

cpp 复制代码
#include <stdio.h>
#include <stdlib.h> // 用于malloc/free

#define MAXSIZE 100  // 队列最大容量
typedef int ElemType; // 队列元素类型

// 顺序队列结构体定义(动态版)
typedef struct {
    ElemType *data; // 动态数组指针
    int front;      // 队头指针
    int rear;       // 队尾指针
} Queue;

// 初始化队列(动态分配版)
Queue* initQueue() {
    Queue *q = (Queue*)malloc(sizeof(Queue));
    q->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
    q->front = 0;
    q->rear = 0;
    return q;
}

// 判断队列是否为空
int isEmpty(Queue *Q) {
    return (Q->front == Q->rear);
}

// 处理队列满(数据搬移)
int queueFull(Queue *Q) {
    if (Q->front > 0) {
        int step = Q->front;
        for (int i = Q->front; i < Q->rear; ++i) {
            Q->data[i - step] = Q->data[i];
        }
        Q->front = 0;
        Q->rear -= step;
        return 1;
    } else {
        printf("队列已满,无法入队!\n");
        return 0;
    }
}

// 入队操作
int enqueue(Queue *Q, ElemType e) {
    if (Q->rear >= MAXSIZE) {
        if (!queueFull(Q)) {
            return 0;
        }
    }
    Q->data[Q->rear++] = e;
    return 1;
}

// 出队操作
ElemType dequeue(Queue *Q) {
    if (isEmpty(Q)) {
        printf("队列为空,无法出队!\n");
        return 0;
    }
    return Q->data[Q->front++];
}

// 获取队头元素(不删除)
int getHead(Queue *Q, ElemType *e) {
    if (isEmpty(Q)) {
        printf("队列为空,无队头元素!\n");
        return 0;
    }
    *e = Q->data[Q->front];
    return 1;
}

// 销毁队列(释放动态内存)
void destroyQueue(Queue *Q) {
    free(Q->data); // 先释放数据数组
    free(Q);       // 再释放队列结构体
}

// 主函数:测试队列操作
int main() {
    Queue *q = initQueue(); // 创建并初始化队列

    // 入队测试
    enqueue(q, 10);
    enqueue(q, 20);
    enqueue(q, 30);
    enqueue(q, 40);
    enqueue(q, 50);

    // 出队测试
    printf("出队元素:%d\n", dequeue(q));
    printf("出队元素:%d\n", dequeue(q));

    // 获取队头测试
    ElemType e;
    if (getHead(q, &e)) {
        printf("当前队头元素:%d\n", e);
    }

    // 继续入队,触发数据搬移
    enqueue(q, 60);
    enqueue(q, 70);

    // 清空队列
    while (!isEmpty(q)) {
        printf("出队元素:%d\n", dequeue(q));
    }

    destroyQueue(q); // 销毁队列,释放内存
    return 0;
}

三、代码总结

  1. 核心概念

    • 顺序队列是用数组实现的 "先进先出(FIFO)" 数据结构。
    • front 指向队头,rear 指向队尾下一个位置,front == rear 表示队空。
    • 静态数组队列存在 "假溢出" 问题,通过数据搬移queueFull函数)解决。
    • 动态版队列用malloc分配内存,更灵活,需手动释放内存避免泄漏。
  2. 核心操作

    • 初始化 :将frontrear置为 0(动态版还需分配内存)。
    • 入队 :向rear位置存元素,rear自增;满时尝试数据搬移。
    • 出队 :取front位置元素,front自增;空时提示错误。
    • 查队头 :读取front位置元素,不修改指针。
    • 销毁:释放动态分配的数组和结构体内存。
  3. 优缺点

    • ✅ 优点:实现简单,访问元素速度快(数组随机访问)。
    • ❌ 缺点:静态版容量固定,假溢出需额外处理;动态版需手动管理内存。
    • 💡 优化方向:可改用循环队列(取模运算)避免假溢出,无需数据搬移。

四、运行结果示例

相关推荐
hanlin032 小时前
刷题笔记:力扣第6题-Z字形变换
笔记·算法·leetcode
努力学习的小廉2 小时前
我爱学算法之——记忆化搜索
算法
m0_730115112 小时前
C++与Python混合编程实战
开发语言·c++·算法
郝学胜-神的一滴4 小时前
Leetcode 969 煎饼排序✨:翻转间的数组排序艺术
数据结构·c++·算法·leetcode·面试
busideyang11 小时前
为什么推挽输出不能接收串口数据,而准双向口可以?
c语言·stm32·单片机·嵌入式硬件·嵌入式
炸膛坦客11 小时前
单片机/C/C++八股:(二十)指针常量和常量指针
c语言·开发语言·c++
爱编码的小八嘎11 小时前
C语言完美演绎4-8
c语言
I_LPL11 小时前
hot100贪心专题
数据结构·算法·leetcode·贪心
颜酱12 小时前
DFS 岛屿系列题全解析
javascript·后端·算法