優先隊列(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 */