优先队列(priority_queue)
优先队列具备队列的通用特性:先进先出(FIFO)
元素由队列尾部插入
出队列的元素则具有当期那队列中最高的优先级
优先队列这种模型 被应用于os的多任务轮转
当可以执行任务时 任务队列中优先级最高的任务被弹出
实现
为了保证队列的push和pop的效率 内部的优先级队列应该用堆排序
// 任务
struct priority_task {
int priority;
};
// 任务队列
struct priority_queue {
struct priority_task **task_list;
int task_index; // 当前的任务数
int task_max; // 最大任务数
};
C/C++实现
https://github.com/sliver-chen/codingutil/tree/master/data_struct/priority_queue
Java实现
Object-C实现
queue.m
#import <Foundation/Foundation.h>
#import "queue.h"
@implementation queue : NSObject
#define DEFAULT_QUEUE_LENGTH (100)
-(void)queue_init
{
mQueue = (struct queue *)malloc(sizeof(struct queue));
if (!mQueue) {
NSLog(@"Alloc task queue failed");
return;
}
mQueue->max = DEFAULT_QUEUE_LENGTH;
mQueue->list = (struct task **)malloc(sizeof(struct task *) * mQueue->max);
if (!mQueue->list) {
NSLog(@"Alloc task list failed");
return;
}
mQueue->cnt = 0;
}
-(void)queue_deinit
{
int i;
if (mQueue && mQueue->list) {
for (i = 0; i < mQueue->max; i++) {
free(mQueue->list[i]);
mQueue->list[i] = nil;
}
}
if (mQueue) {
free(mQueue);
mQueue = nil;
}
}
-(void)push:(struct task *)task
{
struct queue *queue = mQueue;
struct task **tmp = nil;
if (queue->cnt +1 >= queue->max) {
tmp = (struct task **)malloc(sizeof(struct task *) * queue->max);
memcpy(tmp, queue->list, sizeof(struct task *) * queue->max);
free(queue->list);
queue->list = (struct task **)malloc(queue->max * 2 * sizeof(struct task *) * queue->max);
memcpy(queue->list, tmp, sizeof(struct task *) * queue->max);
queue->max *= 2;
}
queue->list[queue->cnt] = (struct task *)malloc(sizeof(struct task));
queue->list[queue->cnt]->priority = task->priority;
queue->cnt++;
[self queue_sort:queue->list queue_size:queue->cnt];
}
-(struct task *)pop
{
struct task *task;
struct queue *queue = mQueue;
if (queue->cnt <= 0) {
return nil;
}
[self queue_swap_task:&queue->list[0] task_y:&queue->list[queue->cnt - 1]];
task = queue->list[queue->cnt - 1];
queue->cnt--;
if (queue->cnt > 1) {
[self queue_sort:queue->list queue_size:queue->cnt];
}
return task;
}
-(void)queue_swap_task:(struct task **)x task_y:(struct task **)y
{
struct task *tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
-(void)queue_adjust:(struct task **)task queue_size:(int)size queue_index:(int)index
{
int max = index;
int left = index * 2 + 1;
int right = index * 2 + 2;
if (left < size && task[left]->priority < task[max]->priority)
max = left;
if (right < size && task[right]->priority < task[max]->priority)
max = right;
if (max != index) {
[self queue_swap_task:&task[max] task_y:&task[index]];
[self queue_adjust:task queue_size:size queue_index:max];
}
}
-(void)queue_sort:(struct task **)task queue_size:(int)size
{
int i = 0;
for (i = size / 2 - 1; i >= 0; i--) {
[self queue_adjust:task queue_size:size queue_index:i];
}
for (i = size - 1; i >= 1; i--) {
[self queue_swap_task:&task[0] task_y:&task[i]];
[self queue_adjust:task queue_size:i queue_index:0];
}
}
@end
queue.h
#ifndef queue_h
#define queue_h
#import <Foundation/Foundation.h>
struct task {
int priority;
};
struct queue {
struct task **list;
int cnt;
int max;
};
@interface queue : NSObject {
struct queue *mQueue;
}
-(void)queue_init;
-(void)queue_deinit;
-(void)push:(struct task *)task;
-(struct task *)pop;
-(void)queue_swap_task:(struct task **)x task_y:(struct task **)y;
-(void)queue_adjust:(struct task **)task queue_size:(int)size queue_index:(int)index;
-(void)queue_sort:(struct task **)task queue_size:(int)size;
@end
#endif /* queue_h */