數據結構之隊列

隊列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱爲隊尾,進行刪除操作的端稱爲隊頭。


隊列特性:先進先出(FIFO)——先進隊列的元素先出隊列。來源於我們生活中的隊列(先排隊的先辦完事)。

隊列有下面幾個操作:

  • InitQueue()   ——初始化隊列
  • EnQueue()        ——進隊列
  • DeQueue()        ——出隊列
  • IsQueueEmpty()——判斷隊列是否爲空
  • IsQueueFull()    ——判斷隊列是否已滿


//
//  Header.h
//  隊列
//
//  Created by mouweng on 17/3/19.
//  Copyright © 2017年 隊列. All rights reserved.
//

#ifndef Header_h
#define Header_h
#include<iostream>
using namespace std;


class MyQueue
{
public:
    MyQueue(int QueueCapacity);//創建隊列
    virtual ~MyQueue();        //銷燬隊列
    void ClearQueue();         //清空隊列
    bool QueueEmpty() const;   //判空隊列
    bool QueueFull() const;    //判斷爲滿
    int QueueLength() const;   //返回隊列長度
    bool EnQueue(int element); //新隊列入隊
    bool DeQueue(int &element);//首元素出隊
    void QueueTraverse();      //遍歷隊列
private:
    int *m_pQueue;             //隊列數組指針
    int m_iQueueLength;        //隊列元素個數
    int m_iQueueCapacity;      //隊列數組容量
    int m_iHead;
    int m_iTail;
};

#endif /* Header_h */



我們所知道,隊列可以是直行也可以是環形,之所以把隊列設成環形的原因呢,是可以節省內存空間。

下面分別給出兩種隊列的代碼


直行隊列源碼如下:

//
//  Header.h
//  直行隊列
//
//  Created by mouweng on 17/3/20.
//  Copyright © 2017年 直行隊列. All rights reserved.
//

#ifndef Header_h
#define Header_h

#include<iostream>
using namespace std;


class MyQueue
{
public:
    MyQueue(int QueueCapacity);//創建隊列
    virtual ~MyQueue();        //銷燬隊列
    void ClearQueue();         //清空隊列
    bool QueueEmpty() const;   //判空隊列
    bool QueueFull() const;    //判斷爲滿
    int QueueLength() const;   //返回隊列長度
    bool EnQueue(int element); //新隊列入隊
    bool DeQueue(int &element);//首元素出隊
    void QueueTraverse();      //遍歷隊列
private:
    int *m_pQueue;             //隊列數組指針
    int m_iQueueLength;        //隊列元素個數
    int m_iQueueCapacity;      //隊列數組容量
    int m_iHead;
    int m_iTail;
};

#endif /* Header_h */

//
//  main.cpp
//  直行隊列
//
//  Created by mouweng on 17/3/20.
//  Copyright © 2017年 直行隊列. All rights reserved.
//

#include <iostream>
using namespace std;
#include "Header.h"

MyQueue::MyQueue(int QueueCapacity)
{
    m_iQueueCapacity= QueueCapacity;
    m_iHead=0;
    m_iTail=0;
    m_iQueueLength=0;
    m_pQueue=new int[m_iQueueCapacity];
}
MyQueue::~MyQueue()
{
    delete [] m_pQueue;
    m_pQueue=NULL;
}

void MyQueue::ClearQueue()
{
    m_iHead=0;
    m_iTail=0;
    m_iQueueLength=0;
}



bool MyQueue::QueueEmpty() const
{
    if(m_iQueueLength==0)
        return true;
    else
        return false;
}
bool MyQueue::QueueFull() const
{
    if(m_iQueueLength==m_iQueueCapacity)
        return true;
    else
        return false;
}



int MyQueue::QueueLength() const
{
    return m_iQueueLength;
}


bool MyQueue::EnQueue(int element)
{
    if(QueueFull())
    {
        return false;
    }
    else
    {
        m_pQueue[m_iTail]=element;
        m_iTail++;
        m_iQueueLength++;
        return true;
    }
    
}

bool MyQueue::DeQueue(int &element)
{
    if(QueueEmpty())
    {
        return false;
    }
    else
    {
        element = m_pQueue[m_iHead];
        m_iHead++;
        m_iQueueLength--;
        return true;
    }
}

void MyQueue::QueueTraverse()
{
    cout<<endl;
    for(int i=m_iHead;i<m_iTail;i++)
    {
        cout<<m_pQueue[i]<<endl;
    }
    cout<<endl;
}



int main(int argc, const char * argv[])
{
    MyQueue *p=new MyQueue(10);
    
    p->EnQueue(10);
    p->EnQueue(12);
    p->EnQueue(16);
    p->EnQueue(18);
    p->EnQueue(20);
    p->QueueTraverse();
    
    int e=0;
    p->DeQueue(e);
    cout<<e<<endl;
    
    p->DeQueue(e);
    cout<<e<<endl;
    
    p->EnQueue(21);
    p->EnQueue(22);
    p->QueueTraverse();
    
    cout<<endl;
    p->ClearQueue();
    
    p->QueueTraverse();
    
    p->EnQueue(20);
    p->EnQueue(30);
    p->QueueTraverse();
    
    delete p;
    p=NULL;
    return 0;
}



環形隊列源碼如下:

//
//  main.cpp
//  環形隊列
//
//  Created by Anthony on 17/3/19.
//  Copyright © 2017年 隊列. All rights reserved.
//

#include <iostream>
using namespace std;
#include "Header.h"

MyQueue::MyQueue(int QueueCapacity)
{
    m_iQueueCapacity= QueueCapacity;
    m_iHead=0;
    m_iTail=0;
    m_iQueueLength=0;
    m_pQueue=new int[m_iQueueCapacity];
}
MyQueue::~MyQueue()
{
    delete [] m_pQueue;
    m_pQueue=NULL;
}

void MyQueue::ClearQueue()
{
    m_iHead=0;
    m_iTail=0;
    m_iQueueLength=0;
}



bool MyQueue::QueueEmpty() const
{
    if(m_iQueueLength==0)
        return true;
    else
        return false;
}
bool MyQueue::QueueFull() const
{
    if(m_iQueueLength==m_iQueueCapacity)
        return true;
    else
        return false;
}



int MyQueue::QueueLength() const
{
    return m_iQueueLength;
}


bool MyQueue::EnQueue(int element)
{
    if(QueueFull())
    {
        return false;
    }
    else
    {
        m_pQueue[m_iTail]=element;
        m_iTail++;
        m_iTail=m_iTail%m_iQueueCapacity;//因爲是一個環形隊列
        m_iQueueLength++;
        return true;
    }

}

bool MyQueue::DeQueue(int &element)
{
    if(QueueEmpty())
    {
        return false;
    }
    else
    {
        element = m_pQueue[m_iHead];
        m_iHead++;
        m_iHead=m_iHead%m_iQueueCapacity;//因爲是一個環形隊列
        m_iQueueLength--;
        return true;
    }
}

void MyQueue::QueueTraverse()
{
    cout<<endl;
    for(int i=m_iHead;i<m_iHead+m_iQueueLength;i++)
    {
        cout<<m_pQueue[i%m_iQueueCapacity]<<endl;
    }
    cout<<endl;
}



int main(int argc, const char * argv[])
{
    MyQueue *p=new MyQueue(4);
    
    p->EnQueue(10);
    p->EnQueue(12);
    p->EnQueue(16);
    p->EnQueue(18);
    p->EnQueue(20);
    p->QueueTraverse();
    
    int e=0;
    p->DeQueue(e);
    cout<<e<<endl;
    
    p->DeQueue(e);
    cout<<e<<endl;
    
    p->EnQueue(20);
    p->EnQueue(22);
    p->QueueTraverse();
    
    cout<<endl;
    p->ClearQueue();
    
    p->QueueTraverse();
    
    p->EnQueue(20);
    p->EnQueue(30);
    
    
    
    
    
    
    delete p;
    p=NULL;
    
    
    
    
    return 0;
}



接下來繼續給大家延時更加靈活更加節省空間的隊列實現方式,是通過鏈表來粗存隊列的元素,爲鏈表隊列。

//
//  Header.h
//  鏈表隊列
//
//  Created by mouweng on 17/3/20.
//  Copyright © 2017年 鏈表隊列. All rights reserved.
//

#ifndef Header_h
#define Header_h
#include<iostream>
using namespace std;


class MyQueue
{
public:
    MyQueue();//創建隊列
    virtual ~MyQueue();        //銷燬隊列
    void ClearQueue();         //清空隊列
    bool QueueEmpty() const;   //判空隊列
    int QueueLength() const;   //返回隊列長度
    bool EnQueue(int element); //新隊列入隊
    bool DeQueue();//首元素出隊
    void QueueTraverse();      //遍歷隊列
private:
    class Node
    {
    public:
        int data;
        Node *next;
        void PrintData()
        {
            cout<<data<<endl;
        }
    };
    Node *m_pQueue;             //隊列數組指針
    int m_iQueueLength;        //隊列元素個數
    int m_iHead;
    int m_iTail;
};
#endif /* Header_h */

//
//  main.cpp
//  鏈表隊列
//
//  Created by mouweng on 17/3/20.
//  Copyright © 2017年 鏈表隊列. All rights reserved.
//

#include <iostream>
using namespace std;
#include "Header.h"

MyQueue::MyQueue()
{
    m_iHead=0;
    m_iTail=0;
    m_iQueueLength=0;
    m_pQueue=new Node;
    m_pQueue->data=0;
    m_pQueue->next=NULL;
}

MyQueue::~MyQueue()
{
    ClearQueue();
    delete m_pQueue;
}

void MyQueue::ClearQueue()
{
    m_iHead=0;
    m_iTail=0;
    m_iQueueLength=0;
    Node *currentNode=m_pQueue->next;
    while(currentNode!=NULL)
    {
        Node *temp=currentNode->next;
        delete currentNode;
        currentNode= temp;
    }
    m_pQueue->next=NULL;
}



bool MyQueue::QueueEmpty() const
{
    if(m_iQueueLength==0)
        return true;
    else
        return false;
}


int MyQueue::QueueLength() const
{
    return m_iQueueLength;
}


bool MyQueue::EnQueue(int element)
{
    Node *temp=m_pQueue;
    Node *currentNode= new Node;
    if(currentNode==NULL)
        return false;
    currentNode->data=element;
    while(temp->next!=NULL)
        temp=temp->next;
    currentNode->next=temp->next;
    temp->next=currentNode;
    m_iQueueLength++;
    return true;
}

bool MyQueue::DeQueue()
{
    if(QueueEmpty())
    {
        return false;
    }
    else
    {
        Node *temp=m_pQueue;
        for(int i=0;i<m_iQueueLength-1;i++)
            temp=temp->next;
        Node *aftertemp=temp->next;
        temp->next=aftertemp->next;
        delete aftertemp;
        m_iQueueLength--;
        return true;
    }
}

void MyQueue::QueueTraverse()
{
    cout<<endl;
    Node *temp=m_pQueue;
while(temp->next!=NULL)
{
    temp=temp->next;
    temp->PrintData();
}
    cout<<endl;
}



int main(int argc, const char * argv[])
{
    MyQueue *p=new MyQueue();
    
    p->EnQueue(10);
    p->EnQueue(12);
    p->EnQueue(16);
    p->EnQueue(18);
    p->EnQueue(20);
    p->QueueTraverse();
    p->QueueLength();
    
    p->DeQueue();
    p->DeQueue();
    p->QueueTraverse();
    
    p->EnQueue(21);
    p->EnQueue(22);
    p->QueueTraverse();
    
    cout<<endl;
    p->ClearQueue();
    
    p->QueueTraverse();
    
    p->EnQueue(20);
    p->EnQueue(30);
    p->QueueTraverse();
    
    delete p;
    p=NULL;
    return 0;
}







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章