数据结构—队列的实现(顺序表)

本文详细介绍了队列数据结构的特点及其实现方式,包括“先进先出”原则、队列的初始化、销毁、入队列、出队列等基本操作,并通过示例代码展示了如何解决队列空间浪费的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构中的队列有“先进先出”的特点,意思是最先被存进队列中的数据,总是最先被取走

一个队列只有初始化,销毁,入队列,出队列和取队首元素,这些限制往往使在操作数据时更安全,代码容易实现,出现BUG的机会就很少


上图队列,如过进行了多次入队列和出队列,就会是head之前的空间浪费,如下图


为了避免这种浪费空间的测操作,当每次head 和 tail 只要到达最后一个元素,操作完成就让他们回到对列的最前面,即head = 0 或 tail = 0,这样head == taill 时,可能是空对列,也可能是满对列,所以判断对列是否满了出现困难,在对列的机构体中加上一个size成员,用来判断是否对列已满

头文件(SeqQueue.h)

#pragma once

typedef char QueueType;

typedef struct SeqQueue{
    QueueType* place;   //队列的空间
    size_t head;        //队首标记
    size_t tail;        //队尾标记
    size_t size;       //对列当前存储元素的个数
    size_t max_size;  //对列最大存储元素个数
}SeqQueue;


void SeqQueueInit(SeqQueue* queue);  //队列初始化

void DestroyQueue(SeqQueue* queue);    //销毁队列

void SeqQueueIn(SeqQueue* queue, QueueType value);    //入队列

void SeqQueueOut(SeqQueue* queue);    //出队列

int SeqQueueFront(SeqQueue* queue, QueueType* output_value);     //取队首元素

头文件的实现(SeqQueue.c)

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

void SeqQueueInit(SeqQueue* queue) {
    queue->max_size = 1;
    queue->size = 0;
    queue->head = 0;
    queue->tail = 0;
    queue->place = malloc(queue->max_size * sizeof(SeqQueue));
    if(queue->place == NULL) {
        printf("malloc 失败!\n");
        exit(1);
    }
}

void DestroyQueue(SeqQueue* queue) {
    if(queue == NULL) {
        return;
    }
    free(queue->place);
    queue->place = NULL;
    queue->max_size = 0;
    queue->size = 0;
    queue->head = 0;
    queue->tail = 0;
}

void SeqQueueIn(SeqQueue* queue, QueueType value) {
    if(queue == NULL) {
        return;
    }
    if(queue->size >= queue->max_size) {
        queue->max_size = 2 * queue->max_size + 1;
        QueueType* new_place  = malloc(queue->max_size * sizeof(SeqQueue));
        int i = 0;
        if(queue->tail == queue->head) {
            for(i = 0; i < queue->tail; i++) {
                new_place[i] = queue->place[i];
            }
            queue->tail = i;
            for(i = 1; i <= (queue->size - queue->head); i++) {
                new_place[queue->max_size - i] = queue->place[queue->size - i];
            }
            queue->head = queue->max_size - i;
        }
        else if(queue->tail > queue->head) {
            for(i = 0; i < queue->size; i++) {
                new_place[i] = queue->place[i];
            } 
        }
        free(queue->place);
        queue->place = new_place;
    }
    if(queue->tail == queue->max_size) {
        queue->tail = 0;
    }
if(queue->head == queue->max_size) {
        queue->head = 0;
    }
queue->place[queue->tail] = value; queue->tail++; queue->size++;}void SeqQueueOut(SeqQueue* queue) { if(queue == NULL) { return; } if(queue->size == 0) { return; } if(queue->head == queue->max_size) { queue->head = 0; } queue->head++; queue->size--;}int SeqQueueFront(SeqQueue* queue, QueueType* output_value) { if(queue == NULL || output_value == NULL) { *output_value = 0; return 0; } if(queue->size == 0) { *output_value = 0; return 0; }    
*output_value = queue->place[queue->head]; return 1;}/////////////////////////////////////////////////////以下为测试代码///////////////////////////////////////////////////void TestQueue() { SeqQueue queue; SeqQueueInit(&queue); SeqQueueIn(&queue, 'a'); SeqQueueIn(&queue, 'b'); SeqQueueIn(&queue, 'c'); SeqQueueIn(&queue, 'd'); int ret; QueueType value; ret = SeqQueueFront(&queue, &value); printf("expected a, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected b, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected c, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected d, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected 0, actrual %d\n", value); printf("expected 0, actrual %d\n", ret); SeqQueueOut(&queue);}int main(){ TestQueue(); return 0;}

实验结果



补充:队列满了的情况有两种

第一种:

只需要从旧的空间把head和tail之间的数据对应复制到新的空间

第二种:


把旧0-tail的数据复制到新空间的0-tail

把head到最后一个数据 之间的数据按顺序复制到新空间的最后面



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值