1.队列的概念------只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表;
进行插入操作的一端称为队尾(入队列)
进行删除操作的一端称为队头(出队列)
队列具有先进先出(FIFO)的特性
2.队列的性质-----队尾插入,队头山删除
3.队列存储结构
顺序队列------队头指针不动,要搬移大量元素
队头指针移动,存在假溢出
假溢出:顺序队列因多次入队列和出队列操作后出现的尚有存储空间但不
能再进行入队列操作的溢出
真溢出:顺序队列最大存储空间已经存满而又要求进行入队列操作所引起
的溢出。
解决假溢出的办法就是循环队列,即将头尾相接的顺序存储队列。 但循环队列又面临着数组可能会溢出的问题
那么循环队列如何判断队列空和满呢?
- 少用一个存储单元
- 设置一个标志位
- 设置一个计数器
//.h
#pragma once//防止头文件被重复引用
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node
{
DataType _data;//队列的数据类型
struct Node* _pNext;//指向下一个结点
}Node,*pNode;
typedef struct Queue
{
pNode _pHead;//指向队头的指针
pNode _pTail;//指向队尾的指针
}Queue;
void QueueInit(Queue* q);//队列的初始化
pNode BuyNode(DataType data);//创建新队列
void QueuePush(Queue* q, DataType data);//入队列
void QueuePop(Queue* q);//出队列
DataType QueueFront(Queue* q);//取队头元素
DataType Queueback(Queue* q);//取队尾元素
int QueueSize(Queue* q);//获取队列中元素的个数
int QueueEmpty(Queue* q);//检测队列是否为空
//Queue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
//队列的初始化
void QueueInit(Queue* q)
{
assert(q);
q->_pHead = NULL;
q->_pTail = NULL;
}
//创建新队列
pNode BuyNode(DataType data)
{
pNode pNewNode = (pNode)malloc(sizeof(Node));
if (NULL == pNewNode)
{
return NULL;
}
else
{
pNewNode->_data = data;
pNewNode->_pNext = NULL;
}
return pNewNode;
}
//入队列(相当于尾插)
void QueuePush(Queue* q, DataType data)
{
assert(q);
pNode pNewNode = BuyNode(data);
if (NULL == q->_pTail)//若链队为空,则新结点是队头又是队尾
{
q->_pHead = pNewNode;
q->_pTail = pNewNode;
}
else
{
q->_pTail = q->_pTail->_pNext;
q->_pTail = pNewNode;
}
}
//void QueuePrint(Queue* q)//打印队列
//{
// while (q->_pHead)
// {
// printf("%d-->", q->_pHead->_data);
// q->_pHead = q->_pHead->_pNext;
// }
// printf("NULL\n");
//}
//出队列
void QueuePop(Queue* q)
{
assert(q);
if (NULL == q->_pHead)
{
return;
}
//一个元素
if (NULL == q->_pHead->_pNext)
{
q->_pHead = NULL;
free(q->_pHead);
return;
}
//多个元素
else
{
q->_pHead = q->_pHead->_pNext;
}
free(q->_pHead->_pNext);
q->_pHead->_pNext = NULL;
}
//取队头元素
DataType QueueFront(Queue* q)
{
assert(q);
return q->_pHead->_data;
}
//取队尾元素
DataType Queueback(Queue* q)
{
assert(q);
return q->_pTail->_data;
}
//获取队列中元素的个数
int QueueSize(Queue* q)
{
assert(q);
int count = 0;
while (q->_pHead)
{
count++;
q->_pHead = q->_pHead->_pNext;
}
return count;
}
//检测队列是否为空
int QueueEmpty(Queue* q)
{
if (NULL == q)
{
return 0;
}
return 1;
}
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
void testQueuePush()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePush(&q, 5);
}
void testQueuePop()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePush(&q, 5);
QueuePop(&q);
QueuePop(&q);
}
void testQueue()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePush(&q, 5);
printf("%d\n", QueueFront(&q));//取队头元素
printf("%d\n", Queueback(&q));//取队尾元素
printf("%d\n", QueueSize(&q));//获取队列中元素的个数
printf("%d\n", QueueEmpty(&q));//检测队列是否为空
}
int main()
{
//testQueuePush();//入队列
//testQueuePop();//出队列
testQueue();
system("pause");
return 0;
}