队列是一种常见的数据结构,具有先进先出的特点。
其中内部有一个首节点和尾节点,分别称为队首和队尾。
今天便实现一下无头不循环队列。代码实现:
/*
这时queue.h文件
包括了queue各种操作函数的声明和queueNode及queue的结构声明
*/
#pragma once
#ifndef _QUEUE_H_
#define _QUEUE_H_
typedef int QUDataType;
//实现无头不循环队列
typedef struct QueueNode
{
struct QueueNode* _next;
QUDataType _data;
}QueueNode;
typedef struct Queue
{
QueueNode* _front;
QueueNode* _rear;
}Queue;
void QueueInit(Queue* pq);//初始化队列
void QueueDestory(Queue* pq);//销毁队列
void QueuePush(Queue*pq, QUDataType x);//入队列
void QueuePop(Queue*pq);//出队列
QUDataType QueueFront(Queue* pq);//取对首元素
QUDataType QueueBack(Queue*pq);//取队尾元素
int QueueEmpty(Queue*pq);//队列是否为空
int QueueSize(Queue*pq);//队列元素个数
void TestQueue();
#endif}
/*
queue.c文件,包含所有函数的实现及测试
*/
#include"queue.h"
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
void QueueInit(Queue* pq)
{
assert(pq != NULL);
pq->_front = pq->_rear = NULL;
}
void QueueDestory(Queue* pq)
{
assert(pq != NULL);
QueueNode*tmp =NULL;
while (pq->_front->_next)
{
tmp = pq->_front;
pq->_front = pq->_front->_next;
free(tmp);
tmp = NULL;
}
}
void QueuePush(Queue*pq, QUDataType x)
{
assert(pq != NULL);
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
if (!newNode)
{
return;//插入失败
}
newNode->_data = x;
newNode->_next = NULL;
if (pq->_front == pq->_rear&&pq->_front==NULL)//这里注意入队第一个节点和后续节点的方式不同
{
pq->_front = pq->_rear = newNode;
}
else
{
pq->_rear->_next = newNode;
pq->_rear = newNode;
}
}
void QueuePop(Queue*pq)
{
assert(pq != NULL);
QueueNode*cur = pq->_front;
pq->_front = pq->_front->_next;
free(cur);
cur = NULL;
}
QUDataType QueueFront(Queue* pq)
{
assert(pq != NULL);
return pq->_front->_data;
}
QUDataType QueueBack(Queue*pq)
{
assert(pq != NULL);
return pq->_rear->_data;
}
int QueueEmpty(Queue*pq)
{
assert(pq != NULL);
return pq->_front == pq->_rear;
}
int QueueSize(Queue*pq)
{
assert(pq != NULL);
int count = 0;
QueueNode*cur = pq->_front;
while (cur)
{
count++;
cur = cur->_next;
}
return count;
}
void QueuePrint(Queue*pq)
{
assert(pq != NULL);
QueueNode*cur = pq->_front;
while (cur)
{
printf("%d ->", cur->_data);
cur = cur->_next;
}
printf("rear\n");
}
void TestQueue()
{
Queue qu;
QueueInit(&qu);
QueuePush(&qu, 1);
QueuePush(&qu, 2);
QueuePush(&qu, 3);
QueuePush(&qu, 4);
QueuePush(&qu, 5);
printf("queue首元素:%d\n", QueueFront(&qu));
printf("queue未元素:%d\n", QueueBack(&qu));
printf("queue中元素个数:%d\n", QueueSize(&qu));
QueuePrint(&qu);
QueuePop(&qu);
printf("queue首元素:%d\n", QueueFront(&qu));
printf("queue未元素:%d\n", QueueBack(&qu));
printf("queue中元素个数:%d\n", QueueSize(&qu));
QueuePrint(&qu);
QueuePop(&qu);
printf("queue首元素:%d\n", QueueFront(&qu));
printf("queue未元素:%d\n", QueueBack(&qu));
printf("queue中元素个数:%d\n", QueueSize(&qu));
QueuePrint(&qu);
QueueDestory(&qu);
}
以上就是queue的所有实现。和stack一样,看起来比较简单,但是在实际中有许多应用场景,例如:敲黑板!!!操作系统的作业中断,网络连接的请求包及一些复杂的问题,如二叉树的非递归层序遍历等。