数据结构-队列

来源:互联网 发布:网络电话卡怎么使用 编辑:程序博客网 时间:2024/06/04 19:09

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。队列的实现有顺序队列、循环队列和链表队列。这里我用了循环队列和链表队列两种。

顺序队列:
与顺序表一样,顺序队列需要分配一块连续的区域来存储队列的元素,需事先定义数据大小。当队列满入队是会出现上溢的现象,队列空出队会产生下溢的想象。这是后要想继续操作,需要对数据进行移动,效率不佳。

循环队列:
循环队列多使用一个数据大小的空间用来表示队列空或者队列满。也就是说循环队列的存储空间中最大数据个数加一(倘若不牺牲着一个数据大小的空间,就需要额外声明一个标志位flag。初始情况下flag=0,front=rear表示队列空。第二次front=rear,flag=1,表示队列满)。循环队列中中有三种状态:

  1. front==rear ( 队列为空状态 )
  2. front!=(rear+1)%maxSize ( 队列的一般状态 )
  3. front==(rear+1)%maxSize ( 队列为满的状态 )

如下图所示,循环队列中能存取的最大数据个数为7个,但需要申请8个数据大小的空间。第一种情况中:队列中没有数据,此时front=rear=0,队列为空;第二种情况中:队列中有一个数据,front=0、rear=1,队列处于一般状态,既能进队也能出队;第三种情况:队列满,front=0,rear=7,此时满足front=(rear+1)%maxSize。在队列常用的操作:打印、入队、出队、获取队头、队尾数据值中。打印、入队、出队、获取队尾数据值中要注意该队列是循环队列,可能出现rear>front的情况,需要处理一下。




代码:

#include<iostream>using namespace std;class arrayQueue{    int front;    int rear;    int* queue;    int maxSize;public:    arrayQueue() {}    arrayQueue(int maxS)     {        front = rear = 0;        queue = new int[maxS+1];        maxSize = maxS+1;    }    ~arrayQueue()    {        del();    }    void dis();//打印队列元素    void del();//删除    void push(int item);//item入队    void pop();//出队    void creat(int num);//创建num个元素的测试队列    bool isEmpty();//是否空    bool isFull();//是否空    bool getFront(int &val);//读取队头元素    bool getRear(int &val);//读取队尾元素};void arrayQueue::dis(){    if (!isEmpty())    {        for (int i = front;i != rear;i=(i+1)%maxSize)        {            if ((i + 1) % maxSize != rear)            {                cout << queue[i] << "->";            }            else                cout << queue[i] << endl;        }    }    else        cout << "队列空。" << endl;}void arrayQueue::del(){    delete[] queue;    front = rear = maxSize = 0;}void arrayQueue::push(int item){    if (!isFull())    {        queue[rear] = item;        rear =(rear+1)%maxSize;    }    else    {        cout << "队列满。" << endl;    }}void arrayQueue::pop(){    if (!isEmpty())    {        front = (front +1) % maxSize;    }    else    {        cout << "队列空。" << endl;    }}void arrayQueue::creat(int num){    for (int i = 0;i < num;i++)        push(i+1);}bool arrayQueue::isEmpty(){    return front == rear;}bool arrayQueue::isFull(){    return (rear + 1) % maxSize == front;}bool arrayQueue::getFront(int& val){    if (!isEmpty())    {        val = queue[front];        return true;    }    else    {        cout << "队列空。" << endl;        return false;    }}bool arrayQueue::getRear(int& val){    if (!isEmpty())    {        val = queue[(rear-1+maxSize)%maxSize];        cout << val << endl;        return true;    }    else    {        cout << "队列空。" << endl;        return false;    }}int main(){    int a;    arrayQueue t(20);    t.creat(20);    t.dis();    return 0;}

链表队列:
链式队列是基于单链表的存储表示,队头指针front指向队头结点,队尾指针rear指向队尾结点。链表中所有的结点都必须通过这两个指针访问到,并且队头端只能用来删除结点,队尾端用来插入结点。如下图所示:n个元素的队列中,队头指针指向链表中第一个数据、队尾指针指向链表中最后一个数据,其中出、入队方向就是箭头描述的方向。




代码:

#include<iostream>using namespace std;class queNode{public:    int element;    queNode* next;    queNode() {}    queNode(int e, queNode* n) :element(e), next(n) {}};class queList{public:    queNode* front;    queNode* rear;    int length;    queList() {}    ~queList()    {        del();    }    void dis();//打印队列元素    void del();//删除    void push(int item);//item入队    void pop();//出队    void creat(int num);//创建测试队列    bool isEmpty();//是否空    bool getFront(int &val);//读取队头元素    bool getRear(int &val);//读取队尾元素};void queList::dis(){    if (!isEmpty())    {        queNode* t = front;        while (t != NULL)        {            if (t->next != NULL)            {                cout << t->element<< "<-";            }            else            {                cout << t->element << endl;            }            t = t->next;        }    }    else    {        cout << "队列空。" << endl;    }}void queList::del(){    if (!isEmpty())    {        while (front != NULL)//每轮循环开始时,t与front的值相等,不存在访问空指针内容        {            rear = front;            front = front->next;            delete(rear);        }        rear = NULL;        length = 0;    }}void queList::push(int item){    queNode* newNode = new queNode(item, NULL);    if (length != 0)    {        rear->next = newNode;        rear = newNode;    }    else    {        front = rear = newNode;    }    length += 1;}void queList::pop(){    if (!isEmpty())    {        queNode* t = front;        front = front->next;        length -= 1;        if (length == 0)            rear = NULL;        delete(t);    }}void queList::creat(int num){    if (num > 0)    {        for (int i = 1;i <= num;i++)            push(i);    }}bool queList::isEmpty(){    return (length == 0);}bool queList::getFront(int& val){    if (!isEmpty())    {        val = front->element;        return true;    }    else        return false;}bool queList::getRear(int& val){    if (!isEmpty())    {        val = rear->element;        return true;    }    else        return false;}int main(){    queList t;    t.creat(10);    t.dis();    return 0;}

链式队列中发现了一个以前一直没发现的问题。当一个指针指向的空间已经被释放后,它的值是什么?访问它会怎么样?它的值还是被释放掉的那块空间的地址,访问它程序会崩溃。

0 0
原创粉丝点击