动态循环队列的实现--->单端队列

来源:互联网 发布:淘宝店关注排名 编辑:程序博客网 时间:2024/05/16 17:07
  • 上述通过数组实现的循环队列申请的空间是固定的,在使用的过程中无法随时进行更改,这里希望通过动态数组的方式来实现循环队列;
  • 需要特殊考虑的是加倍技术,也就是在队列使用过程中的动态扩容,参照栈的实现,需要使用malloc函数realloc函数来实现,但是初始队列里面可能已经包含元素,所以这里需要考虑的是将元素需要进行复制;
  • 原始队列为满表示队列为满的情况
  • 这里有一个位置是不填充元素的,首先将这个从下标0,也就是C的位置进行展开
    将上述的位置进行展开
  • 如果直接进行加倍并且进行元素的复制,得到的结果是
    这里写图片描述
  • 但是在保证队列里面元素相对位置不变的情况下,下面这种方式应该更好;
    这里写图片描述
  • 对于使用第二种方式进行复制的分析:

    • 1.如果front的初始位置为0,也就是说这个队列是一个满队列,这种情况下的复制就比较简单;
    if (start < 2){    cout << start << endl;    copy(Queue + 1, Queue + 1 + MAX_SIZE - 1, newQueue);}
    • 2.否则对于数据的复制就分为两部分,首先是front部分的复制,然后是rear部分的复制;
    else    {        copy(Queue + start, Queue + start + MAX_SIZE, newQueue);        copy(Queue, Queue + QueueInfo[0].rear + 1, newQueue + MAX_SIZE - start);}
  • 首先是队列初始化模块:
typedef struct{    int key;} elements;typedef struct{    int rear;    int front;} Info;int MAX_SIZE = 8;Info QueueInfo[1];void QueueInit( elements **Queue, Info *QueueInfo){    *Queue = (elements *)malloc(sizeof(elements) * MAX_SIZE);    if (Queue == NULL)    {        fprintf(stderr, "Malloc error\n");        exit(EXIT_FAILURE);    }    QueueInfo[0].rear = 0;    QueueInfo[0].front = 0;}
  • 然后是判断队列满了之后的处理:
elements *QueueFull(elements *Queue){    elements *newQueue;    newQueue = (elements *)malloc(2 * MAX_SIZE * sizeof(elements));    if (newQueue == NULL)    {        fprintf(stderr, "Malloc error\n");        exit(EXIT_FAILURE);    }    int start = (QueueInfo[0].front + 1) % MAX_SIZE;    if (start < 2)    {        cout << start << endl;        copy(Queue + 1, Queue + 1 + MAX_SIZE - 1, newQueue);    }        else        {            copy(Queue + start, Queue + start + MAX_SIZE, newQueue);            copy(Queue, Queue + QueueInfo[0].rear + 1, newQueue + MAX_SIZE - start);        }    QueueInfo[0].front = 2 * MAX_SIZE - 1;    QueueInfo[0].rear = MAX_SIZE - 1;    for (int i = 0; i < MAX_SIZE; i++)    {        cout << Queue[i].key << " ";    }    cout << endl;    MAX_SIZE *= 2;    free(Queue);    Queue = newQueue;    return Queue;}
  • 然后是添加元素,并可能调用上面的函数
elements *AddQ(elements *Queue, int data){    QueueInfo[0].rear = (QueueInfo[0].rear + 1) % MAX_SIZE;    if (QueueInfo[0].front == QueueInfo[0].rear)        Queue = QueueFull(Queue);    Queue[QueueInfo[0].rear].key = data;    return Queue;}elements DeleteQ(elements *Queue){    if (QueueInfo[0].rear == QueueInfo[0].front)    {        fprintf(stderr, "The Queue is empty\n");        exit(EXIT_FAILURE);    }    QueueInfo[0].front = (QueueInfo[0].front + 1) % MAX_SIZE;    return Queue[QueueInfo[0].front];}
  • 然后是判断队列是否为满
int  IsFull(){    return (QueueInfo[0].rear + 1) % MAX_SIZE == QueueInfo[0].front ?           true : false;}
  • 判断是否为空
int IsEmpty(){    return (QueueInfo[0].front%MAX_SIZE==QueueInfo[0].rear) ?         true : false;}

上面的参数都进行了返回值的接收,因为是传值调用,因为这个是C++文件,也是可以改成引用传递的
* 完整的代码

#include <iostream>#include <cstdlib>#include <cstdio>#define true 1#define false 0using namespace std;typedef struct{    int key;} elements;typedef struct{    int rear;    int front;} Info;int MAX_SIZE = 8;Info QueueInfo[1];elements *QueueFull(elements *Queue){    elements *newQueue;    newQueue = (elements *)malloc(2 * MAX_SIZE * sizeof(elements));    if (newQueue == NULL)    {        fprintf(stderr, "Malloc error\n");        exit(EXIT_FAILURE);    }    int start = (QueueInfo[0].front + 1) % MAX_SIZE;    if (start < 2)    {        cout << start << endl;        copy(Queue + 1, Queue + 1 + MAX_SIZE - 1, newQueue);    }        else        {            copy(Queue + start, Queue + start + MAX_SIZE, newQueue);            copy(Queue, Queue + QueueInfo[0].rear + 1, newQueue + MAX_SIZE - start);        }    QueueInfo[0].front = 2 * MAX_SIZE - 1;    QueueInfo[0].rear = MAX_SIZE - 1;    for (int i = 0; i < MAX_SIZE; i++)    {        cout << Queue[i].key << " ";    }    cout << endl;    MAX_SIZE *= 2;    free(Queue);    Queue = newQueue;    return Queue;}void QueueInit( elements **Queue, Info *QueueInfo){    *Queue = (elements *)malloc(sizeof(elements) * MAX_SIZE);    if (Queue == NULL)    {        fprintf(stderr, "Malloc error\n");        exit(EXIT_FAILURE);    }    QueueInfo[0].rear = 0;    QueueInfo[0].front = 0;}elements *AddQ(elements *Queue, int data){    QueueInfo[0].rear = (QueueInfo[0].rear + 1) % MAX_SIZE;    if (QueueInfo[0].front == QueueInfo[0].rear)        Queue = QueueFull(Queue);    Queue[QueueInfo[0].rear].key = data;    return Queue;}elements DeleteQ(elements *Queue){    if (QueueInfo[0].rear == QueueInfo[0].front)    {        fprintf(stderr, "The Queue is empty\n");        exit(EXIT_FAILURE);    }    QueueInfo[0].front = (QueueInfo[0].front + 1) % MAX_SIZE;    return Queue[QueueInfo[0].front];}int  IsFull(){    return (QueueInfo[0].rear + 1) % MAX_SIZE == QueueInfo[0].front ?           true : false;}int IsEmpty(){    return (QueueInfo[0].front%MAX_SIZE==QueueInfo[0].rear) ?         true : false;}int main(){    elements *Queue = NULL;    QueueInit(&Queue, QueueInfo);    AddQ(Queue, 10);    AddQ(Queue, 9);    AddQ(Queue, 8);    AddQ(Queue, 7);    AddQ(Queue, 6);    AddQ(Queue, 5);    Queue = AddQ(Queue, 4);    cout << IsFull() << endl;    cout << IsEmpty() << endl;//  Queue = AddQ(Queue, 3);//  AddQ(Queue, 2);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  cout << "My Queue Delete " << endl;//  cout << "MAX_SIZE " << MAX_SIZE << endl;//  DeleteQ(Queue);//  DeleteQ(Queue);//  DeleteQ(Queue);//  DeleteQ(Queue);//  DeleteQ(Queue);//  DeleteQ(Queue);//  DeleteQ(Queue);//  DeleteQ(Queue);//  DeleteQ(Queue);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);//  AddQ(Queue, 1);    cout << "My Queue contains:\n" << endl;    for (int i = 0; i < MAX_SIZE; i++)    {        cout << Queue[i].key << " ";    }    return 0;}