vs2019已测试运行正常
每个接口均有注释,这瓜保熟。
text.c(含菜单)
#include "Queue.h"
void menu()
{
printf("***********************************\n");
printf("**0. 退出 1. 入队 **\n");
printf("**2. 出队 3. 删顶 **\n");
printf("**4. 打印 5. 队长 **\n");
printf("**6. 判空 **\n");
printf("***********************************\n");
}
int main()
{
Queue s1;
QueueInit(&s1);
int input = 0;
do
{
menu();
printf("请输入选择:>");
scanf("%d", &input);
switch (input)
{
case exitd:
{
QueueDestroy(&s1);
printf("退出成功\n");
break;
}
case push:
{
QueueData x = 0;
printf("请输入要入队的数据\n");
scanf("%d", &x);
QueuePush(&s1, x);
printf("入队成功\n");
break;
}
case front:
{
printf("取队头元素成功\n队头为:> %d\n",
QueueFront(&s1));
break;
}
case pop:
{
QueuePop(&s1);
printf("删除队头元素成功\n");
break;
}
case show:
{
ShowQueue(&s1);
break;
}
case size:
{
int size = QueueSize(&s1);
printf("队长为:>%d\n", size);
break;
}
case empty:
{
bool tmp = QueueEmpty(&s1);
if (tmp == true)
{
printf("队空\n");
}
else
{
printf("队不为空\n");
}
break;
}
default:
{
printf("选择错误,请重新选择\n");
break;
}
}
} while (input);
return 0;
}
Queue.c(接口的定义及注释)
#include "Queue.h"
void QueueInit(Queue* p)//队列的初始化
{
assert(p);
p->head = NULL;
p->tail = NULL;
}
void QueueDestroy(Queue* p)//队列的销毁
{
assert(p);
if (p->head = NULL)//队已空,不做处理
{
return;
}
//依次销毁第一个结点
//注意tail指向的是最后一个结点
QueueType* cur = p->head;
//开始依次释放空间,循环的结束条件是队头结点被释放了
while (cur)
{
QueueType* next = p->head->next;
free(cur);
cur = next;
}
}
void QueuePush(Queue* p, QueueData x)//队的插入(队尾)
{
assert(p);
QueueType* newnode = (QueueType*)malloc(sizeof(QueueType));
if (newnode == NULL)
{
perror("QueuePush");
exit(-1);
}//申请空间失败,异常退出并报错
newnode->data = x;
newnode->next = NULL;
//插入至队尾
//分两种情况
//一是队为空,要注意队头head也要更新
//二是队不为空,则只需要更新队尾tail
if (p->head == NULL)
{
p->head = newnode;
p->tail = newnode;
}
else
{
p->tail->next = newnode;
p->tail = newnode;
}
}
void QueuePop(Queue* p)//出队,即头删
{
assert(p);
assert(p->head);//若队空则无法出队,断言失败并退出报错
QueueType* cur = p->head->next;//先定义cur来保存队头的下一结点,防止释放空间后无法找到新队头
//释放队头空间
free(p->head);
p->head = cur;//完成队头的更新
}
void ShowQueue(Queue* p)//依次打印队的内容
{
assert(p);
assert(p->head);//队空则无法打印
QueueType* cur = p->head;
while (cur)
{
printf("%d -> ", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
QueueData QueueFront(Queue* p)//取队头元素
{
assert(p);
assert(p->head);//队空则无法取出
//取出队头元素后要释放掉队头的空间并更新队头
//即复用一次出队接口即可
QueueData num = p->head->data;//先保存对头的数据,避免丢失
//删除队头
QueuePop(p);
return num;//返回原队头数据
}
int QueueSize(Queue* p)//统计队的元素 个数
{
assert(p);//不用判断队空了因为队空为0不应该报错退出
QueueType* cur = p->head;//定义cur从队头开始计数
int count = 0;
while (cur)//队空时cur为零,即不进入循环直接返回零
{
count++;
cur = cur->next;
}
return count;
}
bool QueueEmpty(Queue* p)//判断队空
{
assert(p);
return !(p->head);//队空时head为NULL,否则不是
}
Queue.h(接口的声明)
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<stdbool.h>
enum
{
exitd,
push,
front,
pop,
show,
size,
empty
};
typedef int QueueData;
typedef struct QueueType
{
QueueData data;
struct QueueType* next;
}QueueType;
//头删尾插
typedef struct Queue
{
QueueType* head;
QueueType* tail;
}Queue;
void QueueInit(Queue* p);//队列的初始化
void QueueDestroy(Queue* p);//队列的销毁
void QueuePush(Queue* p, QueueData x);//队的插入(队尾)
void QueuePop(Queue* p);//出队,即头删
void ShowQueue(Queue* p);//依次打印队的内容
QueueData QueueFront(Queue* p);//取队头元素
int QueueSize(Queue* p);//统计队的元素 个数
bool QueueEmpty(Queue* p);//判断队空
新手上路,自娱自乐。