数据结构和算法

队列

2018-10-12  本文已影响29人  seniusen

1. 队列的特点?

2. 顺序队列?

顺序队列 数据搬移
class ArrayQueue
{
    private:
        int *data;      // 顺序队列
        int head;       // 队列头索引值
        int tail;       // 队列尾索引值
        int len;        // 队列的大小

    public:
        // 初始化队列,申请一个大小为 n 的数组
        ArrayQueue(int n)
        {
            data = new int[n];
            head = 0;
            tail = 0;
            len = n;
        }

        bool enqueue(int item)
        {
            // 队列头索引值为零且队列尾索引值等于数组长度,队列空间已满,返回 false,入队失败
            if (tail == len && head == 0)
            {
                cout << "queue is full" << endl;
                return false;
            }
            else
            {// 若只有队列尾索引值等于数组长度,向前平移数据
                if (tail == len && head != 0)
                {
                    int num = tail - head;

                    for (int i = 0; i < num; i++)
                    {
                        data[i] = data[len - num + i];
                    }

                    head = 0;
                    tail = num;
                }

                // 队列空间未满,入队,队列尾索引值加 1

                data[tail] = item;
                tail++;
                return true;
            }
        }

        int dequeue()
        {
            // 队列头等于队列尾,队列为空,返回 -1,出队失败
            if (head == tail)
            {
                cout << "queue is empty" << endl;
                return -1;
            }
            // 队列非空,队头元素出队,队列头索引值加 1
            else
            {
                int item = data[head];
                head++;
                return item;
            }
        }
};

2. 链式队列?

链式队列
// 单向链表
struct linked_list
{
    int data;
    linked_list *next;
};

class ListQueue
{
    private:
        linked_list *head;  // 链表队列的头指针
        linked_list *tail;  // 链表队列的尾指针
        int num;            // 队列中元素个数

    public:
        // 初始化队列,增加一个哨兵结点,方便链表操作
        ListQueue()
        {
            head = new linked_list;
            head->data = -1;
            head->next = NULL;
            tail = head; // 头指针和尾指针都指向哨兵
            num = 0;
        }

        // 入队,在链尾插入新结点
        bool enqueue(int item)
        {
            linked_list *node = new linked_list;
            if (node)
            {
                node->data = item;
                node->next = NULL;
                tail->next = node;  // 添加新结点
                tail = node; // 更新尾指针
                num++;
                return true;
            }
            else // 内存不足,无法插入新结点,返回 false
            {
                return false;
            }
        }

        int dequeue()
        {
            // 队列为空,返回 -1,出队失败
            //if (num == 0)
            if (head == tail)
            {
                cout << "queue is empty" << endl;
                return -1;
            }
            // 出队,弹出哨兵结点后第一个结点的值,并删除结点
            else
            {
                if (head->next == tail) // 当队列只有一个结点时,需要更改尾节点指向哨兵
                {
                    tail = head;
                }

                int item = head->next->data;
                num--;
                linked_list * node = head->next;
                head->next = node->next;
                delete node;
                return item;
            }
        }
};

4. 循环队列?

循环队列 队列满
class CircularQueue
{
    private:
        int *data;      // 顺序队列
        int head;       // 队列头索引值
        int tail;       // 队列尾索引值
        int len;        // 队列的大小

    public:
        // 初始化队列,申请一个大小为 n 的数组
        CircularQueue(int n)
        {
            data = new int[n];
            head = 0;
            tail = 0;
            len = n;
        }

        bool enqueue(int item)
        {
            // 队列空间已满,返回 false,入队失败
            if ((tail + 1) % len == head)
            {
                cout << "queue is full" << endl;
                return false;
            }
            else
            {
                // 队列空间未满,入队,队列尾索引值加 1
                data[tail] = item;
                tail++;
                // 到达数组上限,索引值循环到 0
                if (tail == len)
                {
                    tail = 0;
                }
                return true;
            }
        }

        int dequeue()
        {
            // 队列头等于队列尾,队列为空,返回 -1,出队失败
            if (head == tail)
            {
                cout << "queue is empty" << endl;
                return -1;
            }
            // 队列非空,队头元素出队,队列头索引值加 1
            else
            {
                int item = data[head];
                head++;

                // 到达数组上限,索引值循环到 0
                if (head == len)
                {
                    head = 0;
                }
                return item;
            }
        }

        void print()
        {
            cout << head << " " << tail << endl;
        }
};

3. 阻塞队列和并发队列?

阻塞队列 生产者消费者模型

3. 队列在线程池等有限资源池中的应用?

线程池中没有空闲线程时,新的任务请求线程资源时,线程池该如何处理?各种处理策略又是如何实现的呢?

参考资料-极客时间专栏《数据结构与算法之美》

获取更多精彩,请关注「seniusen」!


seniusen
上一篇 下一篇

猜你喜欢

热点阅读