數據結構:優先隊列

優先隊列(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 */
發佈了143 篇原創文章 · 獲贊 18 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章