zoukankan      html  css  js  c++  java
  • 数据结构队列

    排队规则:进入队列的人永远都在队尾,出队的人永远都在队首.

    1.队列初始化

    用rear和front表示队尾和队首.

    在数组表示队列,如下有5个大小的数组A,

    1,2,3,4,5

    那么如果只有入队的操作,队尾从1转移到了5,5是当前的队尾

    出队的时候数组A的1为第一个队首,随着出队的操作,也慢慢向队尾的方向移动.

    这说明一个情况,队首和队尾,刚开始是同个地方,即使是操作也是相同的(在数组中操作就是添加索引值)

    rear=front=0;

    2.判断队空

    第一个反应是应该有一个变量count来记录元素大小
    如果在没有count变量的情况下,那么第二个反应是rear==front==0,那因为我们还是想着依赖某个变量记录元素大小的思维来思考(rear==front==0肯定是对的,但只是其中的一种情况,我们需要一种绝对式,适应不同的情况),一旦发生入队或者出队不一致就会导致队不为空.
    第三个假设:在现实中,从队列移除是真正的移除,而数组的数量却没有改变,只不过更改了队尾和队首在数组中的位置而已,理解这一点至关重要.

    rear==front==(0,1,2,3,4)都是可以的,即保持入队和出队一致就可以了

    3.判断队满

    第一个反应判断rear是否等于数组大小

    以下代码适用于只有入队的操作

    template<typename Type> bool SeqQueue<Type>::Append(const Type item){
        if((m_nrear+1)==m_nMaxSize){
            cout<<"The queue is full!"<<endl;
            return 0;
        }
        m_pelements[m_nrear]=item;
        m_nrear=m_nrear+1;
        return 1;
    }
    
    

    上面的代码有一个假设,就是没有出队.换一种思路思考就是rear和front的距离.

    如下操作,入队到满位置,然后再出队,入队,那么rear+1就会导致数组溢出,由于数组前面索引的元素已经出队,就可以再次使用,所以将rear值恢复到数组0索引值

    m_nrear=(m_nrear+1)%m_nMaxSize;
    

    由于rear和front都是索引值增加,比较值当间隔是1时,就表示为队满(rear和front值不为0)

    if((m_nrear+1)%m_nMaxSize==m_nfront){
        cout<<"The queue is full!"<<endl;
        return 0;
    }
    

    完整代码示例:

    template<typename Type> class SeqQueue{
    public:
        SeqQueue(int sz):m_nrear(0),m_nfront(0),m_nMaxSize(sz){
            m_pelements=new Type[sz];
            if(m_pelements==NULL){
                cout<<"Application Error!"<<endl;
                exit(1);
            }
        }
        ~SeqQueue(){
            delete[] m_pelements;
        }
        void MakeEmpty();               //make the queue empty
        bool IsEmpty();
        bool IsFull();
        bool Append(const Type item);   //insert data
        Type Delete();                  //delete data
        Type Get();                     //get data
        void Print();                   //print the queue
    
    private:
        int m_nrear;
        int m_nfront;
        int m_nMaxSize;
        Type *m_pelements;
        
    };
    
    template<typename Type> void SeqQueue<Type>::MakeEmpty(){
        this->m_nfront=0;
        this->m_nrear=0;
    }
    
    template<typename Type> bool SeqQueue<Type>::IsEmpty(){
        return m_nrear==m_nfront;
    }
    
    template<typename Type> bool SeqQueue<Type>::IsFull(){
        return (m_nrear+1)%m_nMaxSize==m_nfront;
    }
    
    template<typename Type> bool SeqQueue<Type>::Append(const Type item){
        if(IsFull()){
            cout<<"The queue is full!"<<endl;
            return 0;
        }
        m_pelements[m_nrear]=item;
        m_nrear=(m_nrear+1)%m_nMaxSize;
        return 1;
    }
    
    template<typename Type> Type SeqQueue<Type>::Delete(){
        if(IsEmpty()){
            cout<<"There is no element!"<<endl;
            exit(1);
        }
        Type temp=m_pelements[m_nfront];
        m_nfront=(m_nfront+1)%m_nMaxSize;
        return temp;
    }
    
    template<typename Type> Type SeqQueue<Type>::Get(){
        if(IsEmpty()){
            cout<<"There is no element!"<<endl;
            exit(1);
        }
        return m_pelements[m_nfront];
    }
    
    template<typename Type> void SeqQueue<Type>::Print(){
        cout<<"front";
        for(int i=0;i<m_ncount;i++){
            cout<<"--->"<<m_pelements[(m_nfront+i+m_nMaxSize)%m_nMaxSize];
        }
        cout<<"--->rear"<<endl<<endl<<endl;
    }
    

    求队列的队尾元素

    思路:只有全部出队,才能知道队尾元素,先全部出队求出队尾元素存在一个暂存的队列中,然后将暂存的队列中数据还原到原先队列中

    添加一个记录元素count个数的变量

    添加这个变量后的好处有三点

    1. 能够快速求出队尾元素
    2. 方便队满和空的计算
    3. 可以移除rear变量,以count的计算rear的值

    添加了count以后就好理解很多,当然也不一定要移除front变量

    template<typename Type> bool SeqQueue<Type>::IsEmpty(){
        return m_ncount==0;
    }
    
    template<typename Type> bool SeqQueue<Type>::IsFull(){
        return m_ncount==m_nMaxSize;
    }
    
    template<typename Type> bool SeqQueue<Type>::Append(const Type item){
        if(IsFull()){
            cout<<"The queue is full!"<<endl;
            return 0;
        }
        int rear=(m_nfront+m_ncount)%m_nMaxSize;
        m_pelements[rear]=item;
        m_ncount++;
        return 1;
    }
    
    template<typename Type> Type SeqQueue<Type>::Delete(){
        if(IsEmpty()){
            cout<<"There is no element!"<<endl;
            exit(1);
        }
        Type temp=m_pelements[m_nfront];
        m_nfront=(m_nfront+1)%m_nMaxSize;
        m_ncount--;
        return temp;
    }
    

    链队

    好处:不会溢出,所以就没有IsFull的概念,入队和出队的概念一样

    template<typename Type> class QueueNode{
    private:
        friend class LinkQueue<Type>;
        QueueNode(const Type item,QueueNode<Type> *next=NULL)
            :m_data(item),m_pnext(next){}
    private:
        Type m_data;
        QueueNode<Type> *m_pnext;
    };
    
    template<typename Type> class LinkQueue{
    public:
        LinkQueue():m_prear(NULL),m_pfront(NULL){}
        ~LinkQueue(){
            MakeEmpty();
        }
        void Append(const Type item);   //insert data
        Type Delete();                  //delete data
        Type GetFront();                //get data
        void MakeEmpty();               //make the queue empty
        void Print();                   //print the queue
    
        bool IsEmpty() const{
            return m_pfront==NULL;
        }
    
    private:
        QueueNode<Type> *m_prear,*m_pfront;
    };
    
    template<typename Type> void LinkQueue<Type>::MakeEmpty(){
        QueueNode<Type> *pdel;
        while(m_pfront){
            pdel=m_pfront;
            m_pfront=m_pfront->m_pnext;
            delete pdel;
        }
    }
    
    template<typename Type> void LinkQueue<Type>::Append(const Type item){
        if(m_pfront==NULL){
            m_pfront=m_prear=new QueueNode<Type>(item);
        }
        else{
            m_prear=m_prear->m_pnext=new QueueNode<Type>(item);
        }
    }
    
    template<typename Type> Type LinkQueue<Type>::Delete(){
        if(IsEmpty()){
            cout<<"There is no element!"<<endl;
            exit(1);
        }
        QueueNode<Type> *pdel=m_pfront;
        Type temp=m_pfront->m_data;
        m_pfront=m_pfront->m_pnext;
        delete pdel;
        return temp;
    }
    
    template<typename Type> Type LinkQueue<Type>::GetFront(){
        if(IsEmpty()){
            cout<<"There is no element!"<<endl;
            exit(1);
        }
        return m_pfront->m_data;
    }
    
    template<typename Type> void LinkQueue<Type>::Print(){
        QueueNode<Type> *pmove=m_pfront;
        cout<<"front";
        while(pmove){
            cout<<"--->"<<pmove->m_data;
            pmove=pmove->m_pnext;
        }
        cout<<"--->rear"<<endl<<endl<<endl;
    }
    
  • 相关阅读:
    iTOP-4412开发板低功耗高性能的开源硬件平台——上手评测
    迅为三星Exynos 4412开发板四核Cortex-A9ARM安卓linux开发板
    体验更低功耗的开源硬件平台-迅为4412开发板
    【分享】iTOP-4412开发板使用之初体验[多图]
    【嵌入式开发板】大家都在玩儿的4412开发板
    [POJ] 2965.The Pilots Brothers' refrigerator
    [POJ] 1753.Flip Game
    [HDOJ] 1753.大明A+B (大数加法)
    C++ Primer 第五版 一些遇到的注意点记录。
    [HDOJ] 1172.猜数字
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2169127.html
Copyright © 2011-2022 走看看