队列

队列的基本概念:

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表

链队列:

用链表表示的队列简称为链队列。

链队列的表示与实现:

queue.h

//queue.h
//单链队列的表示与实现

//------------队列的链式存储结构----------------
typedef struct QNode{
    QElemType date;
    struct QNode *next;
}QNode, *QueuePtr;

typedef struct {
    QueuePtr front; //队列指针
    QueuePtr rear; //队尾指针
    int len;
}LinkQueue;

//-----------基本操作的函数原型说明---------------

//构造一个空队列Q
Status InitQueue(LinkQueue &Q){
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
    if(!Q.front)
        exit(OVERFLOW);
    Q.front->next = NULL;
    Q.len = 0;
    return OK;

}//InitQueue

//销毁队列Q
Status DestoryQueue(LinkQueue &Q){
    while(Q.front){
        Q.rear = Q.front->next;
        free(Q.front);
        Q.front = Q.rear;
    }
    cout<<"队列销毁成功!"<<endl;
    return OK;
}//DestoryQueue

//清空队列Q
Status ClearQueue(LinkQueue &Q){
    Q.front = Q.rear;
    Q.front->next = NULL;
    return OK;
}//ClearQueue

//判空
Status QueueEmpty(LinkQueue Q){
    if(Q.front == Q.rear){
        return TRUE;
    }else{
        return FALSE;
    }

}//QueueEmpty

//返回Q的元素的个数
int QueueLength(LinkQueue Q){
    return Q.len;
}//QueueLength

//若队列不为空,用e返回队列的头元素,并返回OK,否则返回ERROR
Status GetHead(LinkQueue Q, QElemType &e){
    if(!QueueEmpty(Q)){
        e = Q.front->next->date;
        return OK;
    }else{
        return ERROR;
    }
}//GetHead

//插入元素e为Q的新的队尾元素
Status EnQueue(LinkQueue &Q, QElemType e){
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if(!p)
        exit(OVERFLOW);
    p->date = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    Q.len++;
    return OK;
}//EnQueue

//若队列不为空,则删除Q的队头元素,用e返回其值
//并返回OK,否则返回ERROR
Status DeQueue(LinkQueue &Q, QElemType &e){
    if(Q.front == Q.rear)
        return ERROR;
    QueuePtr p = Q.front->next;
    e = p->date;
    Q.front->next = p->next;
    if(Q.rear == p)
        Q.rear = Q.front;
    free(p);
    Q.len--;
    return OK;
}//DeQueue

//队列的遍历
Status QueueTraverse(LinkQueue Q){
    if(!QueueEmpty(Q)){
        QueuePtr p = Q.front->next;
        while(p){
            cout<<p->date<<"  ";
            p = p->next;
        }
        cout<<endl;
    }else{
        cout<<"这个队列没有元素!"<<endl;
    }
}//QueueTraverse

baes.h

//base.h
//-----公用的常量和类型----------
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
#include<malloc.h>
#include<string.h>

//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2

typedef int Status;
typedef int QElemType;

text.cpp

//text.cpp
//测试队列基本操作

#include "base.h"
#include "queue.h"

int main(){
    LinkQueue Q;
    QElemType e;
    InitQueue(Q);
    cout<<"队列遍历:";
    QueueTraverse(Q);
    for(e = 0; e < 10; e++){
        EnQueue(Q, e);
    }
    cout<<"队列遍历:";
    QueueTraverse(Q);
    cout<<"队列内元素个数为:"<<QueueLength(Q)<<endl;
    DeQueue(Q, e);
    cout<<"删除的队列元素为:"<<e<<endl;
    cout<<"删除元素后队列的遍历:";
    QueueTraverse(Q);
    EnQueue(Q, 15);
    cout<<"插入15后队列的遍历:";
    QueueTraverse(Q);
    GetHead(Q, e);
    cout<<"获得队列的对头元素:"<<e<<endl;
    if(QueueEmpty(Q))
        cout<<"判空:队列为空!"<<endl;
    else
        cout<<"判空:队列不为空!"<<endl;
    ClearQueue(Q);
    cout<<"请空队列后的遍历:";
    QueueTraverse(Q);
    DestoryQueue(Q);
    return OK;
}

链队列程序测试结果:

链队列

图:链队列测试结果

循环队列:

循环队列使用顺序表的存储结构。

循环队列的代码实现:

sqQueu.h

//sqQueue.h
//循环队列的基本操作

//-----循环队列---队列的顺序存储结构------
#define MAXQSIZE 100 //最大队列长度

typedef struct{
    QElemType *base; //初始化的动态分配存储空间
    int front; //头指针,若队列不空,指向队列对头元素
    int rear; //尾指针,若队列不空,指向队列队尾的下一个元素
}SqQueue;

//------循环队列的基本操作的算法描述-------

//构造一个空队列Q
Status InitQueue_Sq(SqQueue &Q){
    Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
    if(!Q.base)
        exit(OVERFLOW);
    Q.front = Q.rear = 0;
    return OK;
}//InitQueue_Sq

//销毁队列Q
Status DestoryQueue_Sq(SqQueue &Q){
   free(Q.base);
   Q.front = Q.rear = 0;
   cout<<"队列销毁成功!"<<endl;
   return OK;
}//DestoryQueue_Sq

//清空队列Q
Status ClearQueue_Sq(SqQueue &Q){
    Q.front = Q.rear = 0;
    return OK;
}//ClearQueue_Sq

//判空
Status QueueEmpty_Sq(SqQueue Q){
    if(Q.front == Q.rear){
        return TRUE;
    }else{
        return FALSE;
    }

}//QueueEmpty_Sq

//返回Q的元素的个数
int QueueLength_Sq(SqQueue Q){
    return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}//QueueLength_Sq

//若队列不为空,用e返回队列的头元素,并返回OK,否则返回ERROR
Status GetHead_Sq(SqQueue Q, QElemType &e){
    if(!QueueEmpty_Sq(Q)){
        e = Q.base[Q.front];
        return OK;
    }else{
        return ERROR;
    }
}//GetHead_Sq

//插入元素e为Q的新的队尾元素
Status EnQueue_Sq(SqQueue &Q, QElemType e){
    if((Q.rear + 1) % MAXQSIZE == Q.front)
        return ERROR;  //队列满
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXQSIZE;
    return OK;
}//EnQueue_Sq

//若队列不为空,则删除Q的队头元素,用e返回其值
//并返回OK,否则返回ERROR
Status DeQueue_Sq(SqQueue &Q, QElemType &e){
    if(Q.front == Q.rear)
        return ERROR; //队列空
    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXQSIZE;
    return OK;
}//DeQueue_Sq

//队列的遍历
Status QueueTraverse_Sq(SqQueue Q){
    if(!QueueEmpty_Sq(Q)){
        int p = Q.front;
        while((p % MAXQSIZE) != Q.rear){
            cout<<Q.base[p++]<<"  ";
        }
        cout<<endl;
        return OK;
    }else{
        cout<<"这个队列没有元素!"<<endl;
        return ERROR;
    }
}//QueueTraverse_Sq

text.cpp

//text.cpp
//测试队列基本操作

#include "base.h"
#include "sqQueue.h"

int main(){
    QElemType e;
    SqQueue SQ;
    InitQueue_Sq(SQ);
    cout<<"队列遍历:";
    QueueTraverse_Sq(SQ);
    for(e = 0; e < 10; e++){
        EnQueue_Sq(SQ, e);
    }
    cout<<"队列遍历:";
    QueueTraverse_Sq(SQ);
    cout<<"队列内元素个数为:"<<QueueLength_Sq(SQ)<<endl;
    DeQueue_Sq(SQ, e);
    cout<<"删除的队列元素为:"<<e<<endl;
    cout<<"删除元素后队列的遍历:";
    QueueTraverse_Sq(SQ);
    EnQueue_Sq(SQ, 13);
    cout<<"插入13后队列的遍历:";
    QueueTraverse_Sq(SQ);
    GetHead_Sq(SQ, e);
    cout<<"获得队列的对头元素:"<<e<<endl;
    if(QueueEmpty_Sq(SQ))
        cout<<"判空:队列为空!"<<endl;
    else
        cout<<"判空:队列不为空!"<<endl;
    ClearQueue_Sq(SQ);
    cout<<"清空队列后的遍历:";
    QueueTraverse_Sq(SQ);
    DestoryQueue_Sq(SQ);
    return OK;
}

循环队列测试结果:

![循环列]https://cshihong.github.io/2017/10/03/%E9%98%9F%E5%88%97/%E5%BE%AA%E7%8E%AF%E9%98%9F%E5%88%97.png

图:循环队列测试结果

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页