数据结构与算法&队列工具

一、队列

1.定义

   队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。
在这里插入图片描述

2.特点

  • 队列有两个端口,一个端口只能出数据,称为队首(head),一个端口只能进数据,称为队尾(tail)。
  • 先入先出,后入后出。

3.其他

  • 队列的控制元素
    1)数据空间
    2)容量
    3)队首指针
    4)队尾指针
  • 队列的基本操作
    1)入队列
    2)出队列
  • 队列的表示
    1)线性存储结构----数组
    2)非线性存储结构----链表

ps:队列和堆栈很像,但是结果决定功能,所以又有所不同。

二、队列工具的基本实现

1.数据结构的实现

关于队列工具的实现 ,相比于链表,数组构造起来应该更好些。
但是如果使用一般的一维数组,又似乎不太好用。
例如,当数列满的时候,需要一个数出队列,一个新数入队列,那么如何实现?难度要将所有数移动一下?不仅麻烦还效率低。所以这时候又使用到了循环数组
在这里插入图片描述实现基本出入队列操作
在这里插入图片描述
通过tail 和head的值,我们可以知道队列里有几个值,当然也有些特殊
在这里插入图片描述已知某队列容量为12;
head = 4; tail = 7时,队列共有多少个有效元素?
head = 7tail = 4时,队列中共有多少个有效元素?
公式:(tail一head+ capacity)%capacity
但是,如果tail和head相同时,到底是满队列?还是空队列?
此时,可以通过上一次操作作为标签来识别是否其数量。
所以最终的控制元素为:

typedef struct QUEUE{
	void **data; //数据空间
	int capacity;//容量
	int head;//队首
	int tail;//队尾
	int lastEvent;//上一次操作标记
}QUEUE;

不要忘记boolean值的定义。有关void**data数据,详情介绍看数据结构与算法&堆栈工具

  • 初始化队列空间
//初始化队列
boolean initQueue(QUEUE **queue, int capacity) {
	if (NULL == queue || NULL != *queue || capacity <= 0) {
		return FALSE;
	}
	*queue = (QUEUE *)calloc(sizeof(QUEUE), 1);
	if (NULL == *queue) {
		return FALSE;
	}
	(*queue)->data = (void **)calloc(sizeof(void *), capacity);
	if (NULL == (*queue)->data) {
		free(*queue);
		*queue = NULL;
		return FALSE;
	}
	(*queue)->capacity = capacity;
	(*queue)->head = 0;
	(*queue)->tail = 0;
	(*queue)->lastEvent = OUT;//刚开始为空,状态为出

	return TRUE;
}
  • 销毁队列
//销毁队列
void destoryQueue(QUEUE **queue) {
	if (NULL == queue || NULL == *queue) {
		return;
	}
	free((*queue)->data);
	free(*queue);
	queue = NULL;
}

2.队列的一些基本功能实现

  • 队列满?
//判断队列空
boolean isQueueEmpty(const QUEUE *queue) {
	if (NULL == queue) {
		return FALSE;
	}

	return OUT == queue->lastEvent && queue->head == queue->tail;
}
  • 队列空
//判断队列满
boolean isQueueFull(const QUEUE *queue) {
	if (NULL == queue) {
		return FALSE;
	}

	return IN == queue->lastEvent && queue->head == queue->tail;
}
  • 基本操作
//入队列
boolean in(QUEUE *queue, void *data) {
	if (NULL == queue || isQueueFull(queue)) {
		return FALSE;
	}
	queue->data[queue->tail] = data;
	queue->tail = (queue->tail + 1) % queue->capacity;
	queue->lastEvent = IN;

	return TRUE;
}
//出队列
boolean out(QUEUE *queue, void **data) {
	if (NULL == queue || NULL == data || isQueueEmpty(queue)) {
		return FALSE;
	}
	*data = queue->data[queue->head];
	queue->head = (queue->head + 1) % queue->capacity;
	queue->lastEvent = OUT;

	return TRUE;
}
  • 读队首元素
//读取队首元素
boolean readQueueHead(QUEUE *queue, void **data) {
	if (NULL == queue || NULL == data || isQueueEmpty(queue)) {
		return FALSE;
	}
	*data = queue->data[queue->head];

	return TRUE;
}

  • 读取队列元素个数
//读取队列有效元素
int getCount(const QUEUE *queue) {
	if (NULL == queue) {
		return -1;
	}
	if (queue->tail == queue->head) {
		return queue->lastEvent == IN ? queue->capacity : 0;
	}
	return (queue->tail - queue->head + queue->capacity) % queue->capacity;
}

三、总结

1.结构决定功能。功能的实现需要结构。
2.不要拖延!!!


笔者水平有限,目前只能描述以上问题,如果有其他情况,可以留言,有错误,请指教,有继续优化的,请分享,谢谢!
完整代码如下:
queue.h代码

#ifndef _SL_QUEUE_H_
#define _SL_QUEUE_H_

typedef unsigned char boolean;
#define   TRUE    1
#define   FALSE   0
#define	  IN 	  1
#define   OUT	  -1


typedef struct QUEUE{
	void **data; //数据空间
	int capacity;//容量
	int head;//队首
	int tail;//队尾
	int lastEvent;//上一次操作标记
}QUEUE;

boolean initQueue(QUEUE **queue, int capacity);
void destoryQueue(QUEUE **queue);
boolean isQueueEmpty(const QUEUE *queue);
boolean isQueueFull(const QUEUE *queue);
boolean in(QUEUE *queue, void *data);
boolean out(QUEUE *queue, void **data);
boolean readQueueHead(QUEUE *queue, void **data);
int getCount(const QUEUE *queue);
#endif

queue.c代码

#include <stdio.h>
#include <malloc.h>

#include "queue.h"
//初始化队列
boolean initQueue(QUEUE **queue, int capacity) {
	if (NULL == queue || NULL != *queue || capacity <= 0) {
		return FALSE;
	}
	*queue = (QUEUE *)calloc(sizeof(QUEUE), 1);
	if (NULL == *queue) {
		return FALSE;
	}
	(*queue)->data = (void **)calloc(sizeof(void *), capacity);
	if (NULL == (*queue)->data) {
		free(*queue);
		*queue = NULL;
		return FALSE;
	}
	(*queue)->capacity = capacity;
	(*queue)->head = 0;
	(*queue)->tail = 0;
	(*queue)->lastEvent = OUT;//刚开始为空,状态为出

	return TRUE;
}
//销毁队列
void destoryQueue(QUEUE **queue) {
	if (NULL == queue || NULL == *queue) {
		return;
	}
	free((*queue)->data);
	free(*queue);
	queue = NULL;
}
//判断队列空
boolean isQueueEmpty(const QUEUE *queue) {
	if (NULL == queue) {
		return FALSE;
	}

	return OUT == queue->lastEvent && queue->head == queue->tail;
}
//判断队列满
boolean isQueueFull(const QUEUE *queue) {
	if (NULL == queue) {
		return FALSE;
	}

	return IN == queue->lastEvent && queue->head == queue->tail;
}
//入队列
boolean in(QUEUE *queue, void *data) {
	if (NULL == queue || isQueueFull(queue)) {
		return FALSE;
	}
	queue->data[queue->tail] = data;
	queue->tail = (queue->tail + 1) % queue->capacity;
	queue->lastEvent = IN;

	return TRUE;
}
//出队列
boolean out(QUEUE *queue, void **data) {
	if (NULL == queue || NULL == data || isQueueEmpty(queue)) {
		return FALSE;
	}
	*data = queue->data[queue->head];
	queue->head = (queue->head + 1) % queue->capacity;
	queue->lastEvent = OUT;

	return TRUE;
}
//读取队首元素
boolean readQueueHead(QUEUE *queue, void **data) {
	if (NULL == queue || NULL == data || isQueueEmpty(queue)) {
		return FALSE;
	}
	*data = queue->data[queue->head];

	return TRUE;
}
//读取队列有效元素
int getCount(const QUEUE *queue) {
	if (NULL == queue) {
		return -1;
	}
	if (queue->tail == queue->head) {
		return queue->lastEvent == IN ? queue->capacity : 0;
	}
	return (queue->tail - queue->head + queue->capacity) % queue->capacity;
}

2020.03.05 家

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值