队列:队头删除,队尾插入
顺序队列
顺序队列的结构设计成环形的原因:
为了使出队时间复杂度为O(1) ,为了解决队列“假溢出”问题
这样环形结构的好处就是:只要队列没有真正的满,永远不会溢出
注意:
为什么要浪费一个空间? 是 为了区分空和满
队头==队尾为空 、 队尾往后一步是队头为满
环形结构front和rear不能直接++
本文件依旧由三个部分组成 queue.h、queue.cpp、main.cpp
queue.h头文件
#pragma once
#include<assert.h>
#include<malloc.h>
#define INIT_SIZE 10
typedef struct Queue
{
int* elem;//存放动态内存地址
int front;//队头指针
int rear;//队尾指针,当前可以插入数据的下标
int queuesize;//队列的总容量,要做到自动扩容,必须加这个成员
}Queue,*PQueue;
//初始化
void InitQueue(PQueue pq);
//入队
bool Push(PQueue pq, int val);
//获取队头元素的值,但不删除
bool GetTop(PQueue pq, int* rtval);
//获取队头元素的值,并且删除
bool Pop(PQueue pq, int* rtval);
//判空
bool IsEmpty(PQueue pq);
//判满
static bool IsFull(PQueue pq);
//扩容
static bool Inc(PQueue pq);
//获取栈中有效数据的个数
int GetLength(PQueue pq);
//销毁
void Destroy(PQueue pq);
queue.cpp 文件
#include"queue.h"
//初始化
void InitQueue(PQueue pq)
{
assert(pq != NULL);
if (pq == NULL)
return;
pq->elem = (int*)malloc(INIT_SIZE * sizeof(int));
pq->front = 0;
pq->rear = 0;
pq->queuesize = INIT_SIZE;
}
//入队
bool Push(PQueue pq, int val)
{
assert(pq != NULL);
if (pq == NULL)
return false;
if (IsFull(pq))
{
Inc(pq);
}
pq->elem[pq->rear] = val;//在队尾插入
pq->rear = (pq->rear + 1) % pq->queuesize;//环形处理
return true;
}
//获取队头元素的值,但不删除
bool GetTop(PQueue pq, int* rtval)
{
assert(pq != NULL);
if (pq == NULL)
return false;
if (IsEmpty(pq))
return false;
*rtval = pq->elem[pq->front];
return true;
}
//获取队头元素的值,并且删除
bool Pop(PQueue pq, int* rtval)
{
assert(pq != NULL);
if (pq == NULL)
return false;
if (IsEmpty(pq))
return false;
*rtval = pq->elem[pq->front];
pq->front = (pq->front + 1) % pq->queuesize;
return true;
}
//判空
bool IsEmpty(PQueue pq)
{
assert(pq != NULL);
if (pq == NULL)
return false;
return (pq->rear == pq->front);
}
//判满
static bool IsFull(PQueue pq)//静态:只自己用,因为对外没有满的概念(一满就扩容)
{
assert(pq != NULL);
if (pq == NULL)
return false;
return ((pq->rear + 1) % pq->queuesize == pq->front);
}
//扩容
static bool Inc(PQueue pq)
{
pq->queuesize *= 2;
pq->elem = (int*)realloc( pq->elem, pq->queuesize*sizeof(int));
assert(pq != NULL);
if (pq == NULL)
return false;//先扩容,再判断
return true;
}
//获取栈中有效数据的个数
int GetLength(PQueue pq)
{
assert(pq != NULL);
if (pq == NULL)
return -1;
return (pq->rear - pq->front + pq->queuesize) % pq->queuesize;
}
//销毁
void Destroy(PQueue pq)
{
assert(pq != NULL);
if (pq == NULL)
return;
free(pq->elem);
pq->elem = NULL;
pq->front = 0;
pq->rear = 0;
pq->queuesize = 0;
}
main.cpp文件 ,用于测试函数是否写成功
#include"queue.h"
#include<stdio.h>
int main()
{
Queue q;
InitQueue(&q);
int val;
for (int i = 0; i < 13; i++)
{
Push(&q, i);
}
GetTop(&q, &val);
printf("%d\n", val);
printf("%d个\n", GetLength(&q));
while(!IsEmpty(&q))
{
Pop(&q, &val);
printf("%d ", val);
}
printf("%d个\n", GetLength(&q));
Destroy(&q);
return 0;
}