循环队列(顺序表实现,链表实现)

循环队列

循环队列是将顺序队列变为一个变成一个环状的空间。头尾指针以及队列元素之间的关系不变,只是在循环队列中,头尾指针“依环状增 1”的操作可用”模“运算来实现。通过取模运算,头指针和尾指针就可以在顺序表空间内以头尾衔接的方式循环移动。

队空条件:Q.front == Q.rear

队满条件:(Q.rear + 1)% MAXQSIZE == Q.rear(少用一个元素空间,即队列空间为m时,有m-1个元素就认为是队满)。

循环队列(顺序表实现)

#include 
#define MAXQSIZE 100 ///队列可能到达的最大长度
#define OK 1
#define ERROR 0
using namespace std;

typedef int QElemType;
typedef int Status;
typedef struct
{
    QElemType *base; ///存储空间的基地址
    int front; ///头指针
    int rear; ///尾指针
}SqQueue;

Status InitQueue(SqQueue &Q) ///循环队列的初始化
{
    Q.base = new QElemType[MAXQSIZE]; ///为队列分配一个最大容量为MAXQSIZE的数组空间
    if(!Q.base) exit(OVERFLOW); ///存储内存失败
    Q.front = Q.rear = 0; ///头指针和尾指针置为0,队列为空
    return OK;
}

int QueueLength(SqQueue Q) ///循环队列的长度
{///返回Q的元素个数,即队列的长度
    return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

Status EnQueue(SqQueue &Q, QElemType e) ///队列入队
{///插入元素e为Q的新的队尾元素
    if( (Q.rear+1)%MAXQSIZE == Q.front) return ERROR; ///尾指针在循环意义上加一等于头指针,表明队满
    Q.base[Q.rear] = e; ///新元素插入队尾
    Q.rear = (Q.rear+1)%MAXQSIZE; ///队尾指针加1
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e) ///循环队列的出队
{///删除Q的队头元素,用e返回其值
    if(Q.front == Q.rear) return ERROR; ///队空
    e = Q.base[Q.front]; ///保存队头元素
    Q.front = (Q.front+1)%MAXQSIZE; ///队头元素加1
    return OK;
}

QElemType GetHead(SqQueue Q) ///取循环队列的队头元素
{///返回队列的队头元素,不修改头指针
    if(Q.front != Q.rear) return Q.base[Q.front]; ///队列非空
}
void Travel(SqQueue Q) ///遍历队列
{
    int x = Q.front;
    while(x != Q.rear)
    {
        cout<< Q.base[x] << " ";
        x++;
        x %= MAXQSIZE;
    }
    cout<< endl << endl;
}
int main()
{
    SqQueue Q;
    QElemType e;
    cout<< "1. 建立队列" << endl;
    cout<< "2. 入队" << endl;
    cout<< "3. 出队" << endl;
    cout<< "4. 队头元素" << endl;
    cout<< "5. 队列长度" << endl;
    cout<< "6. 遍历队列" << endl;
    int choose = -1;
    while(choose)
    {
        cout<< "请选择:";
        cin>> choose;
        switch(choose)
        {
            case 1:
            {
                if(InitQueue(Q)) cout<< "队列建立成功!\n\n";
                else cout<< "队列建立失败\n\n";
            }
            break;
            case 2:
            {
                cout<< "请输入入队元素:";
                cin>>e;
                if(EnQueue(Q, e)) cout<< "入队成功!\n\n";
                else cout<< "入队失败!\n\n";
            }
            break;
            case 3:
            {
                if(DeQueue(Q, e)) cout<< "出队元素为: " << e << endl << endl;
                else cout<< "出队失败!\n\n";
            }
            break;
            case 4:
            {
                if(Q.front == Q.rear) cout<< "队列为空!\n\n";
                else cout<< "队头元素为:" << GetHead(Q) << endl << endl;
            }
            break;
            case 5:
            {
                cout<< "队列长度为:" << QueueLength(Q) << endl << endl;
            }
            break;
            case 6:
            {
                Travel(Q);
            }
        }
    }
    return 0;
}

循环队列(链表实现) 

用带有头结点的单链表存储结构实现队列。 

#include 
#define OK 1
#define ERROR -1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef int Status;
typedef int QElemType;
typedef struct QNode ///队列的存储结构
{
    QElemType data;
    struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
    QueuePtr front; /// 队头指针
    QueuePtr rear; /// 队尾指针
}LinkQueue;
QueuePtr p;
int length = 0;
Status InitQueue(LinkQueue &Q) ///构造一个空队列
{
    Q.front = Q.rear = new QNode; ///生成新结点作为头结点,队头和队尾指针都指向此节点
    Q.front -> next = NULL; ///头结点指针置为空域
    length = 0;
    return OK;
}

Status EnQueue(LinkQueue &Q, QElemType e) ///插入元素e为Q的新的队尾元素
{///和顺序循环队列入队操作不同的是,链队在入队前不需要判断队是否满,而是需要为入队
 ///元素分配一个结点空间
    p = new QNode; ///为入队元素分配结点空间,用指针p指向
    p->data = e; ///将新结点数据域置为e
    p->next = NULL; Q.rear->next = p; ///将新结点插入到队尾
    Q.rear = p; ///修改队尾指针
    length++;
    return OK;
}
Status DeQueue(LinkQueue &Q, QElemType &e) ///删除Q的队头元素,用e返回其值
{
    if(Q.front == Q.rear) return ERROR; /// 若队列为空,返回ERROR
    p = Q.front->next;  /// p指向队头元素
    e = p->data; ///e保存队头元素的值
    Q.front->next = p->next; ///修改头结点的指针域
    if(Q.rear == p) Q.rear = Q.front; ///最后一个元素被删,队尾指针指向头结点
    delete p; ///释放原头元素的空间
    length--;
    return OK;
}
QElemType GetHead(LinkQueue Q) ///返回Q的队头元素,不修改队头指针
{
    if(Q.front != Q.rear) return Q.front->next->data; ///返回队头元素的值,队头指针不变
}
void Travel(LinkQueue Q)
{
    if(Q.front == Q.rear) return ;
    p = Q.front->next;
    while(1)
    {
        cout<< p->data << " ";
        if(p==Q.rear) break;
        p = p->next;
    }
    cout<< endl << endl;
}
int main()
{
    LinkQueue Q;
    QElemType e;
    cout<< "1. 建立队列" << endl;
    cout<< "2. 入队" << endl;
    cout<< "3. 出队" << endl;
    cout<< "4. 队头元素" << endl;
    cout<< "5. 队列长度" << endl;
    cout<< "6. 遍历队列" << endl;
    int choose = -1;
    while(choose)
    {
        cout<< "请选择:";
        cin>> choose;
        switch(choose)
        {
            case 1:
            {
                if(InitQueue(Q)) cout<< "队列建立成功!\n\n";
                else cout<< "队列建立失败\n\n";
            }
            break;
            case 2:
            {
                cout<< "请输入入队元素:";
                cin>>e;
                if(EnQueue(Q, e)) cout<< "入队成功!\n\n";
                else cout<< "入队失败!\n\n";
            }
            break;
            case 3:
            {
                if(DeQueue(Q, e)) cout<< "出队元素为: " << e << endl << endl;
                else cout<< "出队失败!\n\n";
            }
            break;
            case 4:
            {
                if(Q.front == Q.rear) cout<< "队列为空!\n\n";
                else cout<< "队头元素为:" << GetHead(Q) << endl << endl;
            }
            break;
            case 5:
            {
                cout<< "队列长度为:" << length << endl << endl;
            }
            break;
            case 6:
            {
                Travel(Q);
            }
        }
    }
    return 0;
}

 

你可能感兴趣的:(【数据结构】)