目录
3.队列销毁QueueDestroy(Queue* ps);
队列相比于栈的不同
对于队列,刚好和栈相反,先进先出,分为队头和队尾,队尾进数据,出数据在队头,
例如进数据是1234,那么出数据一定是1234
常见的生活中的应用就是队列可以用来实现抽号机
队列实现方式:
1.数组队列
缺点:挪动数据非常麻烦
2.链表队列
实现方式如下:
1.头文件定义queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int QDataType;
typedef struct QueueNode {
QDataType x;
struct QueueNode* next;
}QNode;
typedef struct Queue {//表示队列整体方便出数据和入数据
int size;
QNode* phead;
QNode* ptail;
}Queue;
void QueueInit(Queue* ps);//队列初始化注意这里要改变的是结构体
void QueueDestroy(Queue* ps);//队列销毁也是结构体
void QueuePop(Queue* ps);//队头出
void QueuePush(Queue* ps, QDataType x);//队尾进
QDataType QueueFront(Queue* ps);//获取队头元素
QDataType Queueback(Queue* ps);//获取队尾元素
int Qsize(Queue* ps);//获取size
bool QueueEmpty(Queue* ps);//判断队列是否为空
其中需要注意的是我们在这里定义了两个结构体,定义结构体的数量是取决于我们堆它的需求的,因为队列进数据在队尾,出数据在队头,那么我们就会经常用到头指针和尾指针,以及需要知道整体队列长度时需要用到size,那么就需要一个新的结构体专门用来控制整个队列,那么常规的那个结构体就是用来控制队列中的每一个节点的
有多个数据就放在一个结构体里面,一个结构体定义每个节点的结构,另外一个结构体用来放头指针,尾指针和size,(用来表示整体的链表结构来表示尾指针和头指针
2.队列初始化QueueInit
void QueueInit(Queue* ps) {
assert(ps);
ps->phead = NULL;
ps->ptail = NULL;
ps->size = 0;
}
3.队列销毁QueueDestroy(Queue* ps);
void QueueDestroy(Queue* ps) {//队列释放是链表释放,逐层释放因为链表和数组不同数组给一个首地址因为是连续的直接就释放了
assert(ps);
QNode* cur = ps->phead;
while (cur != NULL) {
cur = cur->next;
free(ps->phead);
ps->phead = cur;
}
ps->phead = ps->ptail = NULL;
}
4.队头进数据QueuePush
void QueuePush(Queue* ps, QDataType x) {
assert(ps);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
newnode->next = NULL;
newnode->x = 0;
if (newnode == NULL) {
perror("malloc error!");
}
else {
if (ps->phead == NULL) {//如果是空栈的话
ps->phead = ps->ptail=newnode;
newnode->x = x;
ps->size++;
}
else {
ps->ptail->next = newnode;
newnode->x = x;
ps->ptail = newnode;
ps->size++;
}
}
}
5.队头进数据 QueuePop
void QueuePop(Queue* ps) {
assert(ps);
assert(!QueueEmpty(ps));
if (ps->phead->next == NULL) {
ps->phead = ps->ptail = NULL;
ps->size--;
}
else {
QNode* cur = ps->phead->next;
free(ps->phead);
ps->phead = cur;
ps->size--;
}
}
6.获取队头元素QDataType QueueFront
QDataType QueueFront(Queue* ps) {
assert(ps);
assert(!QueueEmpty(ps));
return ps->phead->x;
}
7.获取队尾元素QDataType Queueback
QDataType Queueback(Queue* ps) {
assert(ps);
assert(!QueueEmpty(ps));
return ps->ptail->x;
}
8.获取长度int Qsize
int Qsize(Queue* ps) {
assert(ps);
return ps->size;
}
9.队列判空bool QueueEmpty
bool QueueEmpty(Queue* ps) {
assert(ps);
return ps->phead == NULL;
}
小贴士:
在操作内存时一定要注意空指针,栈或队列或链表为空的情况,注意判断是否是野指针,操作的是结构体里节点中的数据还是要改变结构体指针,所传的参数都是不一样的要进行分析和判断