队列的顺序存储实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


队列

队列是限定只允许在表的一端进行插入,而在另一端进行删除的线性表。允许插入的一端称为队尾,通常用一个称为队尾指针(rear)的指针指向队尾元素(最后被插入的元素)所在的位置;允许删除的一端称为队头(队首),通常用一个称为队头指针(front)指向队头元素的前一个位置。


一、队列定义

在这里插入图片描述
在这里插入图片描述

1. 队列的基本操作

在这里插入图片描述

2.普通队列存在的弊端

在这里插入图片描述
如上图,假设需要将元素1 到元素12 全部入队,
当t元素1 到 元素10入队到队列中时,发现队列已经满了,
在这里插入图片描述
此时元素1,2,3依次出队,头指针移动位置
在这里插入图片描述
此时如果使用的是普通队列,想往队列中入队元素是无法入队的,因
为队尾指针已经到了数组的最后一个位置;如果再入队,队尾指针加1,即图中下标为10的位置,明显不存在该位置,入队会发生错误;

即使队头处有空位置,也无法入队元素,这种情况就是假溢出;
所以普通队列的这种方法浪费了内存;

所以下面我们使用循环队列来解决假溢出的问题;

3.循环队列

所谓循环队列,就是将队列存储空间的最后一个位置接到第一个位置,形成逻辑上的环状空间,供队列使用;
在这里插入图片描述
在这里插入图片描述

设计首尾指针的不同方案:

方案一:队尾指针指向队尾下一个元素;

在这里插入图片描述
队空公式 :frontrear,
但是在下图中, 队满的情况下,队尾元素为数组下标为[2]的元素,而下标为[3]的元素为头指针所指元素,但是由于尾指针指向队尾元素下一个元素,所以此时front
rear也成立,那么 front==rear 的时候,到底是队空还是队满呢?
所以这种情况存在歧义;
在这里插入图片描述

所以我们采用牺牲一个存储单元的情况; 队满表示为:
(rear+1)%MAXSIZE==front;
在这里插入图片描述

方案一改进:

在这里插入图片描述

方案二:队尾指针指向队尾元素:

在这里插入图片描述
在这里插入图片描述

方案二改进:
在这里插入图片描述

二、队列的顺序存储实现

1.循环队列的数组实现,队尾指针指向队尾的下一个元素,没有length的辅助变量。

代码如下(示例):

        程序名:seqqueue1.c,此程序演示循环队列的数组实现,队尾指针指向队尾的下一个元素,没有length的辅助变量。
 */

#include <stdio.h>
#include <string.h>

#define MAXSIZE 10       // 循环队列的最大长度,最多可以存放MAXSIZE-1个元素。

typedef int ElemType;

typedef struct
{
        ElemType data[MAXSIZE];         //用数组存储循环队列中的元素。
        int front;                      //头指针,指向队头元素。
        int rear;                       //尾指针,指向队尾元素的下一个元素。

}SeqQueue,*PSeqQueue;

//循环队列初始化操作
void InitQueue(PSeqQueue QQ);

//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ);

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee);

// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee);

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ);

// 清空循环队列。
void Clear(PSeqQueue QQ);

// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ);

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ);

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ);

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee);


int main()
{
        SeqQueue qq;
        
        InitQueue(&qq);

        printf("队列的长度为:%d\n",Length(&qq));

        printf("向队列中插入元素:1,2,3,4,5,6,7,8,9,10。\n");
        ElemType ee;

        ee=1;InQueue(&qq,&ee);
        ee=2;InQueue(&qq,&ee);
        ee=3;InQueue(&qq,&ee);
        ee=4;InQueue(&qq,&ee);
        ee=5;InQueue(&qq,&ee);
        ee=6;InQueue(&qq,&ee);
        ee=7;InQueue(&qq,&ee);
        ee=8;InQueue(&qq,&ee);
        ee=9;InQueue(&qq,&ee);
        ee=10;InQueue(&qq,&ee);

        //向队列中插入多余的元素,看是否会溢出
        ee=11;InQueue(&qq,&ee);
        ee=12;InQueue(&qq,&ee);
        printf("队列的长度为:%d\n",Length(&qq));

        printf("打印队列所有元素:\n");
        PrintQueue(&qq);

        printf("QQ->rear=%d,QQ->front=%d\n",qq.rear,qq.front);

        //将队列中出队
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);


        return 0;
}

//循环队列初始化操作
void InitQueue(PSeqQueue QQ)
{
        Clear(QQ);
}

//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ)
{

        Clear(QQ);
}

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }


        if( ((QQ->rear+1)%MAXSIZE)==QQ->front ){printf("队列已满。\n");return 0;}
        //if( Length(QQ)>=MAXSIZE-1 ){printf("队列已满。\n");return 0;}


        //将元素ee的值复制给队列中的数组  
        memcpy(&QQ->data[QQ->rear],ee,sizeof(ElemType));

        QQ->rear=(QQ->rear+1)%MAXSIZE;

        return 1;
}

//元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if( QQ->rear==QQ->front ){printf("队列为空,出队失败。\n");return 0; }

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));
        QQ->front=(QQ->front+1)%MAXSIZE;

        return 1;
}

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return 0;}


        int len=(QQ->rear-QQ->front+MAXSIZE)%MAXSIZE;

        return len;
}

// 清空循环队列。
void Clear(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return ;}

        memset(QQ->data,0,sizeof(QQ->data));
        QQ->front=QQ->rear=0;

}
// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;

        if( QQ->rear==QQ->front )return 1;
        return 0;

}

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;
        if( ((QQ->rear+1)%MAXSIZE)==QQ->front )return 1;
        return 0;
}

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return ;}

        int ii=QQ->front;

        while(ii!= QQ->rear)
        {
                printf("%-3d ",QQ->data[ii]);
                ii=(ii+1)%MAXSIZE;
        }
        printf("\n");
}

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if(IsEmpty(QQ)==1){printf("队列为空。\n");return 0;}

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));
        return 1;
}
              

2.循环队列的数组实现,队尾指针指向队尾的下一个元素,增加了length的辅助变量。

代码如下(示例):

/*
        程序名:seqqueue1.c,此程序演示循环队列的数组实现,队尾指针指向队尾的下一个元素,增加了length的辅助变量。
 */

#include <stdio.h>
#include <string.h>

#define MAXSIZE 10       // 循环队列的最大长度,最多可以存放MAXSIZE-1个元素。

typedef int ElemType;

typedef struct
{
        ElemType data[MAXSIZE];         //用数组存储循环队列中的元素。
        int front;                      //头指针,指向队头元素。
        int rear;                       //尾指针,指向队尾元素的下一个元素。
        int length;                     //队列的实际长度                //xxx

}SeqQueue,*PSeqQueue;

//循环队列初始化操作
void InitQueue(PSeqQueue QQ);

//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ);

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee);

// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee);

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ);

// 清空循环队列。
void Clear(PSeqQueue QQ);

// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ);

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ);

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ);

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee);


int main()
{
        SeqQueue qq;
               
        InitQueue(&qq);
        
        printf("队列的长度为:%d\n",Length(&qq));
        
        printf("向队列中插入元素:1,2,3,4,5,6,7,8,9,10。\n");
        ElemType ee;
        
        ee=1;InQueue(&qq,&ee);
        ee=2;InQueue(&qq,&ee);
        ee=3;InQueue(&qq,&ee);
        ee=4;InQueue(&qq,&ee);
        ee=5;InQueue(&qq,&ee);
        ee=6;InQueue(&qq,&ee);
        ee=7;InQueue(&qq,&ee);
        ee=8;InQueue(&qq,&ee);
        ee=9;InQueue(&qq,&ee);
        ee=10;InQueue(&qq,&ee);
        
        //向队列中插入多余的元素,看是否会溢出
        ee=11;InQueue(&qq,&ee);
        ee=12;InQueue(&qq,&ee);
        printf("队列的长度为:%d\n",Length(&qq));
        
        printf("打印队列所有元素:\n");
        PrintQueue(&qq);
        
        printf("QQ->rear=%d,QQ->front=%d\n",qq.rear,qq.front);
        
        GetHead(&qq,&ee);
        printf("取队头元素:%d\n",ee);
        
        //将队列中出队
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        
        GetHead(&qq,&ee);
        printf("取队头元素:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        
        
        return 0;
}       

//循环队列初始化操作
void InitQueue(PSeqQueue QQ)
{
        Clear(QQ);
}
//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ)
{

        Clear(QQ);
}

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }


        if( IsFull(QQ)==1 ){printf("队列已满。\n");return 0;}
        //if( Length(QQ)>=MAXSIZE-1 ){printf("队列已满。\n");return 0;}


        //将元素ee的值复制给队列中的数组  
        memcpy(&QQ->data[QQ->rear],ee,sizeof(ElemType));

        QQ->rear=(QQ->rear+1)%MAXSIZE;
        QQ->length++;                           //长度加1

        return 1;
}

//元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if( QQ->length==0 ){printf("队列为空,出队失败。\n");return 0; }

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));

        QQ->front=(QQ->front+1)%MAXSIZE;
        QQ->length--;                           //队列减1

        return 1;
}

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return 0;}


        int len=(QQ->rear-QQ->front+MAXSIZE)%MAXSIZE;

        return len;
}

// 清空循环队列。
void Clear(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return ;}

        memset(QQ->data,0,sizeof(QQ->data));
        QQ->front=QQ->rear=QQ->length=0;

}
// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;

        if( QQ->length==0 )return 1;
        return 0;

}

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;
        if(QQ->length==MAXSIZE-1 )return 1;
        return 0;
}

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return ;}

        int ii=QQ->front;

        while(ii!= QQ->rear)
        {
                printf("%-3d ",QQ->data[ii]);
                ii=(ii+1)%MAXSIZE;
        }
        printf("\n");
}

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if(IsEmpty(QQ)==1){printf("队列为空。\n");return 0;}

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));
        return 1;
}
         

3.循环队列的数组实现,队尾指针指向队尾元素,没有length的辅助变量。

代码实现如下:

/*
        程序名:seqqueue3.c,此程序演示循环队列的数组实现,队尾指针指向队尾元素,没有length的辅助变量。
 */

#include <stdio.h>
#include <string.h>

#define MAXSIZE 10       // 循环队列的最大长度,最多可以存放MAXSIZE-1个元素。

typedef int ElemType;

typedef struct
{
        ElemType data[MAXSIZE];         //用数组存储循环队列中的元素。
        int front;                      //头指针,指向队头元素。
        int rear;                       //尾指针,指向队尾元素的下一个元素。

}SeqQueue,*PSeqQueue;

//循环队列初始化操作
void InitQueue(PSeqQueue QQ);

//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ);

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee);

// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee);

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ);

// 清空循环队列。
void Clear(PSeqQueue QQ);

// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ);

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ);

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ);

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee);


int main()
{
        SeqQueue qq;
        
        InitQueue(&qq);

        printf("队列的长度为:%d\n",Length(&qq));

        printf("向队列中插入元素:1,2,3,4,5,6,7,8,9,10。\n");
        ElemType ee;

        ee=1;InQueue(&qq,&ee);
        ee=2;InQueue(&qq,&ee);
        ee=3;InQueue(&qq,&ee);
        ee=4;InQueue(&qq,&ee);
        ee=5;InQueue(&qq,&ee);
        ee=6;InQueue(&qq,&ee);
        ee=7;InQueue(&qq,&ee);
        ee=8;InQueue(&qq,&ee);
        ee=9;InQueue(&qq,&ee);
        ee=10;InQueue(&qq,&ee);

        //向队列中插入多余的元素,看是否会溢出
        ee=11;InQueue(&qq,&ee);
        ee=12;InQueue(&qq,&ee);
        printf("队列的长度为:%d\n",Length(&qq));

        printf("打印队列所有元素:\n");
        PrintQueue(&qq);

        printf("QQ->rear=%d,QQ->front=%d\n",qq.rear,qq.front);

        GetHead(&qq,&ee);
        printf("取队头元素:%d\n",ee);

        //将队列中出队
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);

        GetHead(&qq,&ee);
        printf("取队头元素:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);

        printf("元素(11、12、13、14、15)入队。\n");
  ee=11;  InQueue(&qq, &ee);
  ee=12;  InQueue(&qq, &ee);
  ee=13;  InQueue(&qq, &ee);
  ee=14;  InQueue(&qq, &ee);
  ee=15;  InQueue(&qq, &ee);

        printf("打印队列所有元素:\n");
        PrintQueue(&qq);
        return 0;
}

//循环队列初始化操作
void InitQueue(PSeqQueue QQ)
{
        Clear(QQ);
}
//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ)
{

        Clear(QQ);
}


// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if( ((QQ->rear+2)%MAXSIZE)==QQ->front ){printf("队列已满。\n");return 0;}
        //if( Length(QQ)>=MAXSIZE-1 ){printf("队列已满。\n");return 0;}

        QQ->rear=(QQ->rear+1)%MAXSIZE;
        //将元素ee的值复制给队列中的数组  
        memcpy(&QQ->data[QQ->rear],ee,sizeof(ElemType));
        return 1;
}

//元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if( (QQ->rear+1)%MAXSIZE == QQ->front ){printf("队列为空,出队失败。\n");return 0; }

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));
        QQ->front=(QQ->front+1)%MAXSIZE;

        return 1;
}

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return 0;}
        int len=(QQ->rear-QQ->front+1+MAXSIZE)%MAXSIZE;
        return len;
}

// 清空循环队列。
void Clear(PSeqQueue QQ)
{
	        if(QQ==NULL){printf("队列不存在。\n");return ;}
        memset(QQ->data,0,sizeof(QQ->data));
        QQ->front=0;
        QQ->rear=MAXSIZE-1;
}

// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;

        if( (QQ->rear+1)%MAXSIZE==QQ->front )return 1;
        return 0;

}

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;
        if( ((QQ->rear+2)%MAXSIZE)==QQ->front )return 1;
        return 0;
}

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return ;}
        int ii=QQ->front;
        while( ii != QQ->rear)
        {
                printf("%-3d ",QQ->data[ii]);

                ii=(ii+1)%MAXSIZE;
        }
        printf("%-3d",QQ->data[ii]);

        printf("\n");

}

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if(IsEmpty(QQ)==1){printf("队列为空。\n");return 0;}

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));
        return 1;
}

4.循环队列的数组实现,队尾指针指向队尾元素,增加了length的辅助变量。

代码实现如下:

/*
        程序名:seqqueue4.c,此程序演示循环队列的数组实现,队尾指针指向队尾元素,增加了length的辅助变量。
 */

#include <stdio.h>
#include <string.h>

#define MAXSIZE 10       // 循环队列的最大长度,最多可以存放MAXSIZE-1个元素。

typedef int ElemType;

typedef struct
{
        ElemType data[MAXSIZE];         //用数组存储循环队列中的元素。
        int front;                      //头指针,指向队头元素。
        int rear;                       //尾指针,指向队尾元素的下一个元素。
        int length;

}SeqQueue,*PSeqQueue;

//循环队列初始化操作
void InitQueue(PSeqQueue QQ);

//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ);

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee);

// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee);

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ);

// 清空循环队列。
void Clear(PSeqQueue QQ);

// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ);

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ);

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ);

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee);


int main()
{
        SeqQueue qq;
             InitQueue(&qq);

        printf("队列的长度为:%d\n",Length(&qq));

        printf("向队列中插入元素:1,2,3,4,5,6,7,8,9,10。\n");
        ElemType ee;

        ee=1;InQueue(&qq,&ee);
        ee=2;InQueue(&qq,&ee);
        ee=3;InQueue(&qq,&ee);
        ee=4;InQueue(&qq,&ee);
        ee=5;InQueue(&qq,&ee);
        ee=6;InQueue(&qq,&ee);
        ee=7;InQueue(&qq,&ee);
        ee=8;InQueue(&qq,&ee);
        ee=9;InQueue(&qq,&ee);
        ee=10;InQueue(&qq,&ee);

        //向队列中插入多余的元素,看是否会溢出
        ee=11;InQueue(&qq,&ee);
        ee=12;InQueue(&qq,&ee);
        printf("队列的长度为:%d\n",Length(&qq));

        printf("打印队列所有元素:\n");
        PrintQueue(&qq);

        printf("QQ->rear=%d,QQ->front=%d\n",qq.rear,qq.front);

        GetHead(&qq,&ee);
        printf("取队头元素:%d\n",ee);

        //将队列中出队
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);

        GetHead(&qq,&ee);
        printf("取队头元素:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);
        if(OutQueue(&qq,&ee)!=0)printf("出队元素为:%d\n",ee);

        printf("元素(11、12、13、14、15)入队。\n");
  ee=11;  InQueue(&qq, &ee);
  ee=12;  InQueue(&qq, &ee);
  ee=13;  InQueue(&qq, &ee);
  ee=14;  InQueue(&qq, &ee);
		
		  ee=15;  InQueue(&qq, &ee);

        printf("队列的长度为:%d\n",Length(&qq));
        printf("打印队列所有元素:\n");
        PrintQueue(&qq);
        return 0;
}

//循环队列初始化操作
void InitQueue(PSeqQueue QQ)
{
        Clear(QQ);
}
//销毁循环队列QQ。
void DestroyQueue(PSeqQueue QQ)
{

        Clear(QQ);
}


// 元素入队,返回值:0-失败;1-成功。
int InQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if( QQ->length==MAXSIZE-1 ){printf("队列已满。\n");return 0;}
        //if( Length(QQ)>=MAXSIZE-1 ){printf("队列已满。\n");return 0;}

        QQ->rear=(QQ->rear+1)%MAXSIZE;
        //将元素ee的值复制给队列中的数组  
        memcpy(&QQ->data[QQ->rear],ee,sizeof(ElemType));
        QQ->length++;
        return 1;
}

//元素出队,返回值:0-失败;1-成功。
int OutQueue(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if( QQ->length==0 ){printf("队列为空,出队失败。\n");return 0; }

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));
        QQ->front=(QQ->front+1)%MAXSIZE;
        QQ->length--;
        return 1;
}

// 求循环队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return 0;}
        return QQ->length;
}

// 清空循环队列。
void Clear(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return ;}
        memset(QQ->data,0,sizeof(QQ->data));
        QQ->front=0;
        QQ->rear=MAXSIZE-1;
        QQ->length=0;
}

// 判断循环队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;

        if( QQ->length==0 )return 1;
        return 0;

}

// 判断循环队列是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqQueue QQ)
{
        if(QQ==NULL)return 0;
        if( QQ->length==MAXSIZE-1 )return 1;
        return 0;
}

// 打印循环队列中全部的元素。
void PrintQueue(PSeqQueue QQ)
{
        if(QQ==NULL){printf("队列不存在。\n");return ;}

        int ii=QQ->front;
        while( ii != QQ->rear)
        {
                printf("%-3d ",QQ->data[ii]);

                ii=(ii+1)%MAXSIZE;
        }
        printf("%-3d",QQ->data[ii]);

        printf("\n");

}

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PSeqQueue QQ, ElemType *ee)
{
        if(QQ==NULL || ee==NULL){printf("队列不存在或者数据元素不存在。\n");return 0; }

        if(IsEmpty(QQ)==1){printf("队列为空。\n");return 0;}

        memcpy(ee,&QQ->data[QQ->front],sizeof(ElemType));
        return 1;
}
		

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值