队列的顺序存储基本代码示例

队列是只能在表的一端进行插入,在另一端进行删除操作的线性表

允许删除元素的一端称为队头,允许插入元素的一端称为队尾

先进先出表 First in First out (FIFO)

队列有两个活动端:设置了队头(front)队尾(rear)两个位置的指针

front和rear指针分别是队头和队尾的下标值

本章仅讨论队列顺序存储的方式

队列的应用:计算机缓存

顺序表中,每删除一个元素,此后所有元素依次向前移动,在顺序存储的队列中,每次出队列的元素必是队头元素,效率低下

入队和出队都是移动指针,不移动元素

入队:指针rear先向前移动一步,将新元素在rear位置插入

出队:指针front先向前移动一步,将下标为front的元素取出

由于rear和front指针只能单方向移动,最终rear和front指针指向数组的最大下标位置,当入队出队操作反复执行时会产生“假溢出”

解决方法:循环队列:采用数学方法将rear和front指针从数组空间最大下标位置移到最小下标位置

数组空间长度M

%求余

//入队
rear=(rear+1)%M;
//出队
front=(front+1)%M;
//队空
front==rear;
//队满
(rear+1)%M=front;

为了判断队列是空还是满,一般将头指针front指向的空间舍弃

循环队列结构体类型描述

typedef struct QUEUE
{
    DataType* queArray;  //存放元素的数组指针
    int front;  //队头
    int rear;   //队尾
    int maxLength;  //队列的最大容量
}Queue;

创建一个队列

C语言 strlen 函数用来求字符串的长度(包含多少个字符)

char是1字节

sizeof 统计出的字符串长度比 strlen() 函数的统计值大 1

原因很简单,sizeof 统计了字符串结尾的\0,而 strlen() 函数没有

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>   //函数strlen() 不计\0
#include<iostream>

using namespace std;

typedef char DataType;  //将char重定义为DataType

typedef struct QUEUE  //queue队列
{
    DataType* queArray;  //存放元素的数组指针queArray
    int front;  //队头front
    int rear;   //队尾rear
    int maxLength;  //队列的最大容量maxLength
}Queue;

//创建一个队列
Queue* CreatQueue(int length)  //最大长度
{
    Queue* queue = (Queue*)malloc(sizeof(Queue));  //结构体Queue
    if (queue)  
    {
        //申请内存
        queue->queArray = (DataType*)malloc(sizeof(Queue));
        //失败则返回NULL
        if (queue->queArray == NULL)
        {
            return NULL;
        }
        queue->front = 0;  //清空队列
        queue->rear = 0;   //清空队列
        //记录最大容量
        queue->maxLength = length;
    }
    return queue;  //返回指向队列的指针queue
}

//销毁队列
void DestoryQueue(Queue* queue)
{
    free(queue->queArray);  //free()
    free(queue);
}

//清空队列
void ClearQueue(Queue* queue)
{
    queue->front = 0;  //清空队列
    queue->rear = 0;   //清空队列
}

//得到队列的长度
int GetQueueLength(Queue* queue) 
{
    int length;
    if (queue->rear >= queue->front)  //队尾>队头
    {
        length = queue->rear - queue->front;
    }
    else  //队尾<队头
    {
        length = queue->rear - queue->front + queue->maxLength;
    }
    return length;
}

//入队
void EnQueue(Queue* queue, DataType data)
{
    if ((queue->rear + 1) % queue->maxLength == queue->front)  //判断队列是否已满
    {
        printf("队列已满");
    }
    else
    {
        //队尾向后移动一位
        queue->rear = (queue->rear + 1) % queue->maxLength; //%取余
        //入队
        queue->queArray[queue->rear] = data;  //插入
    }
}

//出队,仅仅移动队头即可
DataType OutQueue(Queue* queue)
{
    if (GetQueueLength(queue) > 0)  //判断队为非空
    {
        queue->front = (queue->front + 1) % queue->maxLength; //queue->front向后移动一位
        return queue->queArray[queue->front];  //取出queue->front位置的值
    }
    else  //队为空
    {
        return 0;
    }
}

//取队头元素
DataType GetQueueHead(Queue* queue)
{
    if (GetQueueLength(queue) > 0)  //队为非空
    {
        int k = (queue->front + 1) % queue->maxLength;  //头元素下标
        return queue->queArray[k];
    }
    else
    {
        return 0;  //队是空的,返回0
    }
}

//主函数
int main()
{
    const int QueueMax = 100;  //定义队列最大容量
    //创建队列
    Queue* queue = CreatQueue(QueueMax);
    if (queue == NULL)
    {
        return 1;
    }
    printf("连续输入不超过十个字符作为入队列字符");
    char ch[10];
    (void)scanf("%s", &ch);
    for (int i = 0; i < strlen(ch); i++)
    {
        EnQueue(queue, ch[i]);
    }
    printf("字符出队顺序为:");
    //所有元素依次出队直到队空
    while (GetQueueLength(queue) > 0)  //判断非空队列
    {
        printf("出队:%c\n", OutQueue(queue));
    }
    DestoryQueue(queue);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

挣钱钱暴富富

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值