队列
一、什么是队列?
队列可类比为有两个特殊属性的简单链表:
- 新项只能添加到链表末尾
- 只能从链表头开始删除项
通常简称为先进先出,可类比为排队,后来的人跟在链表末尾,然后前面排完队的人先离开。
二、实现队列
清楚了队列的先进先出这一特性,我们似乎可以很快想到这其实不就是链表吗(而且是相当简单的链表。。。),只是赋予了链表一些固定的属性,因此我们可以采用链表实现队列,当然它的一些接口也受链表属性的限制。(这样一来,我们似乎更容易实现,因为少去了考虑如何实现添加到何处,以及从何处删除这些过程。因为队列限制了添加位置以及删除位置)
废话不多说,动手!!!上代码!!!
以下展示一些基本的队列查找、删除、添加等接口实现较之先前的双向链表实现来说是很简单了。
- Queue.h (头文件,类型定义及接口定义)
//Queue.h头文件,包括类型相关定义以及接口相关定义
#ifndef _MYQUEUE_H
#define _MYQUEUE_H
#include <stdbool.h>
/* 第一步、建立抽象数据类型 */
//定义类型,此处类型可依据具体需要更改,但是涉及相应接口实现可能也需要随之变化
typedef struct _item
{
int num;
int value;
}Item;
//定义结点
typedef struct _node
{
Item item;
struct _node * next;
}Node;
//定义队列
typedef struct _queue
{
Node * first; //队列头,指向第一个结点的指针
Node * last; //队列尾,指向最后一个结点的指针
}Queue;
/* 第二步、建立接口 */
//需要一个指向队列的指针类型,初始化队列为空
void InitializeQueue(Queue * ql);
//需要一个指向队列的指针类型,确定初始化为空,如果为空返回true,否则返回false
bool QueueIsEmpty(const Queue * ql);
//需要一个指向队列的指针类型,确定队列是否已满,如果满返回true,否则返回false
bool QueueIsFull(const Queue * ql);
//需要一个指向队列的指针类型,确定队列中的项数,返回一个unsigned int类型的值
unsigned int CountQueueSize(const Queue * ql);
//需要一个指向队列的指针类型,在队列的末尾添加项,返回一个状态表示成功添加,或失败
bool AddToQueue(Queue * ql, Item item);
//需要一个指向队列的指针类型,在队列的开头删除一些项
void DelInQueue(Queue * ql, int amount);
//需要一个指向队列的指针类型,将队列清空
void ClearQueue(Queue * ql);
//需要一个指向队列类型的指针,展示队列
void ShowQueue(const Queue * ql);
#endif
-
Queue.c(接口实现)
实现接口的时候我们可以添加一点printf验证我们的接口是否能完成操作,没问题的话我们再将其注释掉,也算一个调试接口的方法吧。
//Queue.c -- 实现接口
#include <stdio.h>
#include <stdlib.h>
#include "myqueue.h"
//文件内部需要用的辅助函数,static静态定义
static void CopyToItem(Node * p, Item item)
{
p->item = item;
}
void InitializeQueue(Queue * ql)
{
ql->first = ql