数据结构(五)——队列实现及其应用

1、顺序队列的原理

队列是限制在两端进行插入操作和删除操作的线性表
允许进行存入操作的一端称为“队尾”
允许进行删除操作的一端称为“队头”
当线性表中没有元素时,称为“空队”
特点:先进先出(FIFO)
在这里插入图片描述
双端队列
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2、顺序队列的实现

声明结构体

typedef int datatype;
#define N 128

typedef struct {
	datatype data[N];
	int front;
	int rear;
}sequeue;

2.1 创建队列

sequeue * queue_create() {
	sequeue *sq;

	if ((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL) {
		printf("malloc failed\n");
		return NULL;
	}

	memset(sq->data, 0, sizeof(sq->data));
	sq->front = sq->rear = 0;
	return sq;
}

2.2 入队


int enqueue(sequeue *sq, datatype x) {
	if (sq == NULL) {
		printf("sq is NULL\n");
		return -1;
	}

	if ((sq->rear + 1) % N == sq->front) {
		printf("sequeue is full\n");
		return -1;
	}

	sq->data[sq->rear] = x;
	sq->rear = (sq->rear + 1) % N;

	return  0;
}

2.3 出队

datatype dequeue(sequeue *sq) {
	datatype ret;

	ret = sq->data[sq->front];

	sq->front = (sq->front + 1) % N;

	return ret;
}

2.4 空队

int queue_empty(sequeue *sq) {
	if (sq == NULL) {
		printf("sq is NULL\n");
		return -1;
	}

	return (sq->front == sq->rear ? 1 : 0);
}

2.5 满队

int queue_full(sequeue *sq) {
	if (sq == NULL) {
		printf("sq is NULL\n");
		return -1;
	}

	if ((sq->rear + 1) % N == sq->front) {
		return 1;
	}
	else {
		return 0;
	}
}

2.6 清空队列

int queue_clear(sequeue *sq) {
	if (sq == NULL) {
		printf("sq is NULL\n");
		return -1;
	}

	sq->front = sq->rear = 0;

	return 0;
}

2.7 队列释放

sequeue * queue_free(sequeue *sq) {
	if (sq == NULL) {
		printf("sq is NULL\n");
		return NULL;
	}

	free(sq);
	sq = NULL;

	return NULL;
}

3、链式队列的原理在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4、链式队列的实现

声明结构体

typedef int datatype;

typedef struct node {
	datatype data;
	struct node *next;
}listnode , *linklist;

typedef struct {
	linklist front;
	linklist rear;
}linkqueue;

4.1 创建队列

linkqueue * queue_create() {
	linkqueue *lq;

	if ((lq = (linkqueue *)malloc(sizeof(linkqueue))) == NULL) {
		printf("malloc linkqueue failed\n");
		return NULL;
	}

	lq->front = lq->rear = (linklist)malloc(sizeof(listnode));
	if (lq->front == NULL) {
		printf("malloc node failed\n");
		return NULL;
	}
	lq->front->data = 0;
	lq->front->next = NULL;

	return lq;
}

4.2 入队

int enqueue(linkqueue *lq, datatype x) {
	linklist p;

	if (lq == NULL) {
		printf("lq is NULL\n");
		return -1;
	}

	if ((p = (linklist)malloc(sizeof(listnode))) == NULL) {
		printf("malloc node failed\n");
		return -1;
	}
	p->data = x;
	p->next = NULL;

	lq->rear->next = p;
	lq->rear = p;

	return 0;
}

4.3 出队

datatype dequeue(linkqueue *lq) {
	linklist p;

	if (lq == NULL) {
		printf("lq is NULL\n");
		return -1;
	}

	p = lq->front;
	lq->front = p->next;
	free(p);
	p = NULL;

	return (lq->front->data);
}

4.4 空队

int queue_empty(linkqueue *lq) {
	if (lq == NULL) {
		printf("lq is NULL\n");
		return -1;
	}

	return (lq->front == lq->rear ? 1 : 0);
}

4.5 清空队列

int queue_clear(linkqueue *lq) {
	linklist p;

	if (lq == NULL) {
		printf("lq is NULL\n");
		return -1;
	}

	while (lq->front->next) {
		p = lq->front;
		lq->front = p->next;
		printf("clear free:%d\n", p->data);
		free(p);
		p = NULL;
	}
	return 0;
}

4.6 释放队列

linkqueue * queue_free(linkqueue *lq) {
	linklist p;

	if (lq == NULL) {
		printf("lq is NULL\n");
		return NULL;
	}

	while (lq->front) {
		p = lq->front;
		lq->front = p->next;
		printf("free:%d\n", p->data);
		free(p);
	}

	free(lq);
	lq = NULL;

	return NULL;
}


5、栈和队列的应用—球钟问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include "linkqueue.h"
#include "sqstack.h"

int check(linkqueue * lq);

int main(int argc, const char *argv[])
{
	linkqueue *lq;
	sqstack *s_hour, *s_five, *s_min;
	int value;
	int i, min = 0;

	if ((lq = queue_create()) == NULL) {
		return -1;
	}

	for (i = 1; i <= 27; i++) {
		enqueue(lq, i);
	}

	if ((s_hour = stack_create(11)) == NULL) {
		return -1;
	}

	if ((s_five = stack_create(11)) == NULL) {
		return -1;
	}

	if ((s_min = stack_create(4)) == NULL) {
		return -1;
	}

	while (1) {
		min++;
		if (!queue_empty(lq)) {
			value = dequeue(lq);
			if (!stack_full(s_min)) {
				stack_push(s_min, value);
			} else {
				while (!stack_empty(s_min)) {
					enqueue(lq, stack_pop(s_min));
				}
				if (!stack_full(s_five)) {
					stack_push(s_five, value);
				} else {
					while (!stack_empty(s_five)) {
						enqueue(lq, stack_pop(s_five));
					}
					if (!stack_full(s_hour)) {
						stack_push(s_hour, value);
					} else {
						while (!stack_empty(s_hour)) {
							enqueue(lq, stack_pop(s_hour));
						}
						enqueue(lq, value);
						//0:0
						if (check(lq) == 1) {//检查队列是否升序
							break;
						}
					}
				}

			}
		}
	}
	printf("total:%d\n", min);

	printf("dequeue:");
	while (!queue_empty(lq)) 
		printf("%d ", dequeue(lq));
	
	puts("");

	return 0;
}

int check(linkqueue * lq) {
	linklist p;

	if (lq == NULL) {
		printf("lq is NULL\n");
		return -1;
	}

	p = lq->front->next;

	while (p && p->next) {
		if (p->data < p->next->data) {
			p = p->next;
		} else {
			return 0;
		}
	}
	return 1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值