数据结构与算法—队列queue

目录

队列

顺序队列与链式队列

循环队列

1、数组实现,非循环

2、数组实现,循环

阻塞队列(生产者-消费者)

并发队列

线程池使用队列

队列的实现


队列

        先进先出  

        入队enqueue()

        出队deququq()

使用场景:在循环队列、阻塞队列、并发队列,在底层系统、框架、中间件开发,起到至关重要的作用。

顺序队列与链式队列

要点:1)头指针,指向队头;2)尾指针,指向队尾;3)队列大小

1、顺序队列:使用数组实现的队列

顺序队列队列扩容

       队尾到最后空间时,需要扩容。在插入数据时,一点点搬运到新队列中。

2、链式队列:使用链表实现的队列

链式队列

入队:tail->next = new_node;

                tail = tail->next;

出队:head = head->next

循环队列

优点:避免数据搬移

确定队列空和队列满的条件

1、数组实现,非循环

        队满条件 tail == n

        队空条件 head = tail

2、数组实现,循环

        队空 head=tail

        队满 (tail+1)%n = head

阻塞队列(生产者-消费者)

队列为空的时候,从队头取数据会被阻塞,没有数据可以获取,知道队列中有数据才能返回;

如果队列满,插入数据操作会被阻塞,直到有空闲位置再插入,然后返回。

阻塞队列,可协调生产者和消费者的速度。可以有多几个消费者。

并发队列

在多线程情况下,会有多个线程同时操作队列,这时要考虑线程安全问题。加锁。

但加锁粒度比较大,并发低,同一时刻仅允许一个存或取操作。

基于数组的循环队列,利用CAS原子操作,高效实现并发。Disruptor

线程池使用队列

链式实现,可能有更多的请求排队等待,请求处理响应时间过长,针对时间比较敏感的系统,链式不太合适

数组实现,队列大小有限,响应时间相对合理。设置合理的队列大小,也非常讲究。太大导致请求太多,太小无法发挥系统的最大性能。

队列的实现

typedef struct _array_queue
{
        int size;
        int num;
        int head;
        int tail;
        int *array;
}arrayQueue;

#define array_queue_is_empty(arrayQueue)        (arrayQueue->num = 0)
#define array_queue_is_full(arrayQueue) ((arrayQueue->num) == (arrayQueue->size))


arrayQueue *array_queue_create(int size)
{
        arrayQueue *queue = NULL;
        queue = (arrayQueue *)malloc(sizeof(array_queue));
        if(queue==NULL)
                return NULL;

        queue->array = (int *)malloc(sizeof(int)*size);
        if(queue->array == NULL)
        {
                free(queue);
                return NULL;
        }
        queue->size = size;
        queue->num = 0;
        queue->head = 0;
        queue->tail = 0;

        return queue;
}

void array_queue_destory(arrayQueue *queue)
{
        if(queue == NULL)
                return;
        if(queue->array != NULL)
                free(queue->array);

        free(queue);
        return;
}

int array_queue_enqueue(arrayQueue *queue,int data)
{
        if((queue == NULL) || array_queue_is_full(queue))
        {
                return -1;
        }
        queue->num++;
        queue->array[queue->tail]=data;
        queue->tail = (queue->tail +1)%queue->size;
        return 0;
}

int array_queue_dequeue(arrayQueue *queue,int *data)
{
        if((queue == NULL) || array_queue_is_empty(queue))
        {
                return -1;
        }

        *data = queue->array[queue->head];
        queue->num--;
        queue->head = (queue->head + 1)%queue->size;

        return 0;

}

猜你喜欢

转载自blog.csdn.net/WANGYONGZIXUE/article/details/129208551
今日推荐