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;
    }


  • 相关阅读:
    Android--Android studio --布局管理
    Android--Android studio --Activity
    Android--Android studio --app运行
    Android--Android studio 工程目录分析
    Java--Niit-ch2--Location本地化问题
    C--循环实现和递归实现的比较
    C--函数调用
    【未完待续】Java蓝桥杯--算法训练 数学知识的运用
    【未完待续】Java蓝桥杯--算法训练(1)典型问题的递归框架
    NIIT2--JAVA活动(一)制作内部类 正则内部类
  • 原文地址:https://www.cnblogs.com/itrena/p/5926992.html
Copyright © 2011-2022 走看看