zoukankan      html  css  js  c++  java
  • 数据结构基础(14) --链式队列的设计与实现

        链式队列是基于单链表的一种存储表示, 其形状如下图所示:

     

        (队列的队头指针指向单链表的第一个结点队尾指针指向单链表的最后一个结点, 注意没有无用的空[头/尾]节点)

        用单链表表示的链式队列特别适合于数据元素变动比较大的情况, 而且不存在队列满而产生溢出的情况;

     

    链式队列结点构造:

    [这次我们将节点构造成了类LinkQueue的嵌套类]

    struct ChainNode
    {
        ChainNode(const Type &_data, ChainNode *_next = NULL)
            :data(_data), next(_next) {}
    
        Type data;
        ChainNode *next;
    };

    链式队列构造:

    template <typename Type>
    class LinkQueue
    {
        template <typename T>
        friend ostream &operator<<(ostream &os, LinkQueue<T> &queue);
    public:
        LinkQueue();
        ~LinkQueue();
        bool isEmpty() const;
    
        void push(const Type &data);
        void pop();
    
        //返回队首元素
        const Type &front() const;
        //返回队尾元素
        const Type &back() const;
        //清空队列
        void makeEmpty();
    
    private:
        struct ChainNode
        {
            ChainNode(const Type &_data, ChainNode *_next = NULL)
                :data(_data), next(_next) {}
    
            Type data;
            ChainNode *next;
        };
    
    private:
        ChainNode *m_front; //队首指针[注意不是指向一个无用的空节点]
        ChainNode *m_back;  //队尾指针[注意不是指向一个无用的空节点]
    };

    队列的构造与析构:

    template <typename Type>
    LinkQueue<Type>::LinkQueue()
    {
        m_front = m_back = NULL;
    }
    template <typename Type>
    LinkQueue<Type>::~LinkQueue()
    {
        makeEmpty();
    }

    队列的四大操作:

    //入队, 这是链式队列的关键
    template <typename Type>
    void LinkQueue<Type>::push(const Type &data)
    {
        if (isEmpty())
        {
            //如果队列为空
            //则队首与队尾指针共同指向一个新构造的对象
            m_front = m_back = new ChainNode(data);
        }
        else
        {
            //首先让队尾的下一位置指向一个新构造的对象
            m_back->next = new ChainNode(data);
            //然后队尾指针后移
            m_back = m_back->next;
        }
    }
    //出队
    template <typename Type>
    void LinkQueue<Type>::pop()
    {
        if (isEmpty())
            throw std::range_error("queue is empty");
    
        ChainNode *deleteNode = m_front;
        // 队首指针后移
        m_front = m_front->next;
        delete deleteNode;
    }
    //取队首元素
    template <typename Type>
    const Type &LinkQueue<Type>::front() const
    {
        if (isEmpty())
            throw std::range_error("queue is empty");
    
        return (m_front->data);
    }
    //取队尾元素
    template <typename Type>
    const Type &LinkQueue<Type>::back() const
    {
        if (isEmpty())
            throw std::range_error("queue is empty");
    
        return (m_back->data);
    }

    清空队列与判空操作:

    template <typename Type>
    void LinkQueue<Type>::makeEmpty()
    {
        while (!isEmpty())
        {
            pop();
        }
    }
    template <typename Type>
    bool LinkQueue<Type>::isEmpty() const
    {
        return (m_front == NULL);
    }

    输出队列所有元素(以做测试):

    template <typename Type>
    ostream &operator<<(ostream &os, LinkQueue<Type> &queue)
    {
        for (typename LinkQueue<Type>::ChainNode *currentNode = queue.m_front;
                currentNode != NULL;
                currentNode = currentNode->next)
        {
            os << currentNode->data << ' ';
        }
    
        return os;
    }

    -测试代码:

    int main()
    {
        LinkQueue<int> queue;
        for (int i = 0; i < 10; ++i)
        {
            queue.push(rand()%100);
        }
        cout << queue << endl;
    
        cout << queue.front() << endl;
        queue.pop();
        cout << queue.front() << endl;
        cout << queue.back() << endl;
        cout << queue << endl;
    
        LinkQueue<char> cQueue;
        cQueue.push('A');
        cout << "cQueue.front = " << cQueue.front() << endl;
        cout << "cQueue.back = " << cQueue.back() << endl;
        cQueue.pop();
        cout << cQueue << endl;
        try
        {
            cout << "cQueue.front = " << cQueue.front() << endl;
            cout << "cQueue.back = " << cQueue.back() << endl;
        }
        catch(const std::exception &e)
        {
            cerr << e.what() << endl;
        }
    
        return 0;
    }


  • 相关阅读:
    Spark数据读取
    05、TypeScript 中的泛型
    04、TypeScript 中的接口
    03、TypeScript 中的类
    02、TypeScript 中的函数
    01、TypeScript 数据类型
    Vue-router 知识点
    什么是跨域?如何解决跨域问题
    工作中积累的问题、知识点总结100题(0-20)
    封装一个 Promise 对象。了解其原理
  • 原文地址:https://www.cnblogs.com/itrena/p/5926992.html
Copyright © 2011-2022 走看看