数据结构-队列(C语言的简单实现)

简介

  • 队列也是一种数据结构,队列也可以用来存放数字
  • 每次只能向队列里将入一个数字,每次只能从队列里获得一个数字
  • 在队列中,允许插入的一段称为入队口,允许删除的一段称为出队口
  • 它的原则是先进先出(FIFO: first in first out),先进入队列的数据先出去,后进入的后出去。
  • 队列的插入操作称为入队
  • 队列的删除操作称为出队

以下是队列中进行入队和出队的演示操作,数据1先进,也是数据1先出

代码实现

  1. 初始化队列
c 复制代码
typedef struct queue{
    int* elements;  // 存储区
    int cap;  // 队列的容量
    int rear;  // 入队口
    int front;  // 出队口
    int size;  // 队列当前大小
}queue_t;
  1. 初始化队列
c 复制代码
void queue_init(queue_t* pqueue, int cap){
    // 分配存储区空间
    pqueue->elements = malloc(sizeof(int) * cap);
    if(pqueue->elements == NULL){
        printf("内存分配失败\n");
        return;
    }
    // 赋值容量
    pqueue->cap = cap;
    // 此时因为没有收数据,出队口和入队口都是0,队列当前大小也是0
    pqueue->rear = 0;
    pqueue->front = 0;
    pqueue->size = 0;
}
  1. 销毁队列
c 复制代码
void queue_deinit(queue_t* pqueue){
    free(pqueue->elements);
    pqueue->elements = NULL;
    pqueue->cap = 0;
    pqueue->rear = 0;
    pqueue->front = 0;
    pqueue->size = 0;
}
  1. 判断队列是否已满
c 复制代码
int queue_full(queue_t* pqueue){
    // 当size==cap的时候,说明已满,反之则没满
    return pqueue->size == pqueue->cap;
}
  1. 判断队列是否为空
c 复制代码
int queue_empty(queue_t* pqueue){
    // 当size==0的时候,说明为空,反之则不为空
    return pqueue->size == 0;
}

以下是一组入队出队的操作

  1. 入队
c 复制代码
void queue_push(queue_t* pqueue, int data){
    // 参考上面的视频,当此时还存在入队操作时,说明队列还没满,
    // 但是此时rear已经超过索引值了(也就是与cap值相等),需要将rear重置为0;
    if(pqueue->rear == pqueue=>cap)
        pqueue->rear = 0;
    pqueue->elements[pqueue->rear++] = data;
    pqueue->size++;
}
  1. 出队
c 复制代码
int queue_pop(queue_t*  pqueue){
    // 与入队函数类似,当此时还存在出队操作时,说明队列不为空,
    // 但是此时front已经超过索引值了(也就是与cap值相等),需要将front重置为0
    if(pqueue->front == pqueue->cap)
        pqueue->front = 0;
    pqueue->size--;
    return pqueue->elements[pqueue->front++];
}

实例代码

创建三个文件: queue.cqueue.hmain.c,实现上面动图中的操作

  • queue.c定义队列具体的函数
c 复制代码
#include "queue.h"

// 初始化队列
void queue_init(queue_t* pqueue, int cap){
    pqueue->elements = malloc(sizeof(int) * cap);
    if(pqueue->elements == NULL){	
        printf("分配队列存储区失败!\n");
	return;
    }
    pqueue->cap = cap;
    pqueue->rear = 0;
    pqueue->front = 0;
    pqueue->size = 0;
}

// 销毁队列
void queue_deinit(queue_t* pqueue){
    free(pqueue->elements);
    pqueue->elements = NULL;
    pqueue->cap = 0;
    pqueue->rear = 0;
    pqueue->front = 0;
    pqueue->size = 0;
}

// 入队
void queue_push(queue_t* pqueue, int data){
    if(pqueue->rear == pqueue->cap)
	pqueue->rear = 0;
    pqueue->elements[pqueue->rear++] = data;
    pqueue->size++;
}


// 出队
int queue_pop(queue_t* pqueue){
    if(pqueue->front == pqueue->cap)
	pqueue->front = 0;
    pqueue->size--;
    return pqueue->elements[pqueue->front++];
}

//判断队列是否已满
int queue_full(queue_t* pqueue){
    return pqueue->size == pqueue->cap;
}

// 判断队列是否为空
int queue_empty(queue_t* pqueue){
    return pqueue->size == 0;
}
  • queue.h声明队列的相关函数和定义队列
c 复制代码
#ifndef __QUEUE_H
#define __QUEUE_H

#include <stdio.h>
#include <stdlib.h>

// 定义队列
typedef struct queue{
    int* elements;
    int cap;
    int rear;
    int front;
    int size;

}queue_t;

extern void queue_init(queue_t* pqueue, int cap);
extern void queue_deinit(queue_t* pqueue);
extern void queue_push(queue_t* pqueue, int data);
extern int queue_pop(queue_t* pqueue);
extern int queue_full(queue_t* pqueue);
extern int queue_empty(queue_t* pqueue);

#endif
  • main.c主函数使用队列
c 复制代码
#include "queue.h"

int main(void){
    // 1. 创建一个队列
    queue_t queue;
    // 2. 初始化队列
    queue_init(&queue, 4);
    // 3. 入队4个数据
    printf("开始第一次入队(4个数据): ");
    int data = 10;
    for(int i = 0; i < 4; i++){
    	if(!queue_full(&queue)){
	    printf("%d ", data);
	    queue_push(&queue, data);
	    data += 10;
	}
    }
    printf("\n此时还剩%d个数据\n\n", queue.size);
    
    // 4. 出队2个数据
    printf("开始第一次出队(2个数据): ");
    for(int i = 0; i < 2; i++){
        if(!queue_empty(&queue)){
	    data = queue_pop(&queue);
	    printf("%d ", data);
	}
    }
    printf("\n此时还剩%d个数据\n\n", queue.size);
    
    // 5. 入队2个数据
    printf("开始第二次入队(2个数据): ");
    data = 10;
    for(int i = 0; i < 2; i++){
        if(!queue_full(&queue)){
            printf("%d ", data);
            queue_push(&queue, data);
            data += 10;
        }
    }
    printf("\n此时还剩%d个数据\n\n", queue.size);

    // 6. 将所有数据全部取出
    printf("将全部数据取出: ");
    while(!queue_empty(&queue)){
    	data = queue_pop(&queue);
	printf("%d ", data);
    }
    printf("\n此时还剩%d个数据\n\n", queue.size);


    // 销毁队列
    queue_deinit(&queue);
    return 0;
}
相关推荐
M78佐菲5 小时前
c语言学习笔记:排序与查找方法整理
linux·c语言·笔记·学习·算法
wWYy.6 小时前
C++与C的区别
c语言·c++
LuminousCPP7 小时前
数据结构‑二叉树(二):二叉堆从零实现|Heap结构设计 + 建堆优化 + 堆排序深度解析
c语言·数据结构·笔记·二叉树
9 小时前
数据结构第一课:复杂度解析
数据结构
程序员与背包客_CoderZ11 小时前
高性能分布式KV存储引擎RocksDB入门与C/C++编码实战
c语言·开发语言·数据库·c++·分布式·分布式数据库·rocksdb
欧叶冲冲冲11 小时前
Python常见数据结构的CRUD(LeetCode高频版速查)
数据结构·python·leetcode
william_yangshun11 小时前
【大模型部署实战】kimi-k3-in-c 中文版:用 176KB 纯 C99 引擎在 CPU 上跑 Kimi K3 上手指南
c语言·开发语言
_Narcissus_12 小时前
链表算法题和静态链表
数据结构·c++·笔记·算法·链表·ai·力扣
Lyyaoo.12 小时前
【普通数组】【中等】除了自身以外数组的乘积
数据结构·算法·leetcode
Yyyyyy~13 小时前
【C语言】数据类型和变量【下】
c语言