循环优先级队列c语言实现

本文介绍了循环优先级队列的使用方法,代码由c语言实现,但了解相关思想后,使用c++、python等语言也可通过数组来快速实现循环优先级队列


前言

之前写了一篇使用c语言实现循环队列的,后来由于需要,个人又基于它实现了循环优先级队列。


一、循环优先级队列是什么?

之前所介绍的循环队列是先入先出的,很容易用平常的排队来理解。但如果这个队列要支持有紧急情况的人先出队呢?原先那种队列就不再适用了,我们就需要使用本文所提到的特殊队列–优先队列。

优先队列也是一种抽象数据类型。优先队列中的每个元素都有优先级,而优先级高(或者低)的将会先出队,而优先级相同的则按照其在优先队列中的顺序依次出队。

这样采用数组实现时,可以有两种方式,一种是以O(1)复杂度插入,每次在队尾入队,而以O(N)复杂度弹出最小元素;或者以O(N)复杂度插入,保持数组有序,而以O(1)复杂度删除。另一种则是使用堆来实现,堆可以认为是用数组实现的二叉树,可以在O(log N)的复杂度内实现元素的插入和删除。

在本文中采用的是第一种方式,即可在O(n)的时间复杂度内插入,O(1)的复杂度内弹出。

二、c语言实现

1.整体结构

代码如下(示例):

#define QUEUE_SIZE (1024)

struct queue {
	int data[QUEUE_SIZE];
	int priority[QUEUE_SIZE];
	int front;
	int tail;
	int empty;
};

void init(struct queue *);
void enqueue(struct queue *, int, int);
int dequeue(struct queue *);

同前述,data数组用于保存队列中数据,priority用于保存队列中各数据权重,priority值越小,越容先出队,front是队首元素索引,tail是队尾元素索引+1,empty表示队列是否为空。各函数的具体实现如下:

2.函数实现

代码如下(示例):

#include "queue.h"
#include <stdio.h>

void init(struct queue *q)
{
	q->front = q->tail = 0;
	q->empty = 1;
}

// value表示要插入队列的元素的值,prio为其权重
void enqueue(struct queue *q, int value, int prio)
{
	if (!q->empty && q->front == q->tail) {
		printf("queue shouldn't be overflow\n");
		exit(-1);
	}
	q->empty = 0;
	int i = (q->tail - 1 + QUEUE_SIZE) % QUEUE_SIZE, j = q->tail, 
		head = (q->front - 1 + QUEUE_SIZE ) % QUEUE_SIZE;
	// head为队首索引-1,当i==head,意味着队列中所有的元素都比较完毕
	// i表示当前需要与value进行比较的元素的索引,j则为(i+1) % QUEUE_SIZE
	while( i != head) {
		if( q->priority[i] <= prio)
			break;
		q->data[j] = q->data[i];
		q->priority[j] = q->priority[i];
		j = i;
		i = (i - 1 + QUEUE_SIZE) % QUEUE_SIZE;
	}
	q->data[j] = value;
	q->priority[j] = prio;
	q->tail = (q->tail + 1) % QUEUE_SIZE;
}

int dequeue(struct queue *q)
{
	if (q->empty)
		return -1;
	int value = q->data[q->front];
	q->front = (q->front + 1) % QUEUE_SIZE;
	if (q->front == q->tail)
		q->empty = 1;
	return value;
}

与循环队列改动较大的主要是enqueue函数,为实现插入后队列中的元素仍按权重保持有序,显然需要将入队元素插入在合适的位置中;函数中即按照这一思想,从队列尾开始,采用冒泡的方式,将priority值大的元素都向后挪一个单位


总结

以上就是循环队列c语言的简单实现,上述思想也可适用于像c++、java等,都可通过数组来快速实现简单的循环优先级队列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值