您的位置:首页 > 其它

队列的两种存储方式的介绍与实现

2017-07-31 14:38 239 查看

简介

队列是一种特殊的线性表,它的特殊之处在于它必须在队列的头部进行删除元素,在队列尾部插入元素。我们把队列的头部称为对头(front),队列尾部叫做队尾(rear)。进行删除元素位置叫队头(front),进行插入元素的位置叫在队尾(rear)。

队列的存储的数据称为队列元素,因为只能在对头进行删除的操作,队尾进行插入,先插入的先出队,所以我们可以称队列为一种先进先出(FIFO:first in first out )的数据结构。

顺序队列

创建顺序存储结构,我们必须动态申请或静态地分配一块存储位置,设置两个指针来进行管理,分别称为对头head、队尾tail,当队头与队尾相等时

(head==tail)我们称为队空。队头指针指向队列第一个插入的元素,tail指针指向队列最后一个插入元素的下一个位置,当队列中插入一个元素时,tail+1;删除

一个元素时,head+1。

我们来看一个图:



在图中我们可以到,图1.3,当队头元素被删除后,会留下一块存储区域,它并不会再次被使用,所以会造成内存的浪费。图1.4中反应了这样一个现象,当队列所

申请的内存最后一块存储空间被占有时,当想要再插入一个新的元素时,就会产生问题,这种现象称为“假溢出”。

为了避免上述的问题,因此出现了一个新的概念:循环队列。

循环队列

循环队列,我们假想成一个循环模型,如下图所示:

当front==rear时表示队空;当循环出队列、入队列的过程中会发生一种情况,队尾在元素一的位置,队头在元素二的位置,那么头尾指针也恰好指向同一个位置,这时我们称为队满,是不是也是front==rear?



这里我用数组方式来实现循环队列:

typedef int QueType;
typedef int Status;
#define capacity 4
*采用数据存储元素,数组类型为:int
*实现队列初始化、出队列、入队列、统计队列总数、循环遍历队列元素等功能。
*/
typedef struct{

int head;//头
int tail;//尾

QueType queArr[capacity];//队列数组

}myQueue;

//队列初始化
int InitQueue(myQueue *q){
//q = (myQueue *)malloc(sizeof(myQueue));
q->head = q->tail = 0 ;//头和尾相等,此时为空
return 0;
}

//判断队列是否为空
//为空返回0,否则为-1
int QueueEmpity(myQueue *q){
if(q->head == q->tail){//首尾相等,队列为空
return 0;
}
return -1 ;
}

//判断队列是否已满
//为空返回0,否则为-1
int QueueFull(myQueue *q){
//避免和队列为空时冲突。队列中实际还差一个位置。
if(q->head == (q->tail+1)%(capacity)){//为满时,
return 0;
}
return -1 ;
}

//入队
Status EnQueueEle(myQueue *q , QueType ele){

if(QueueFull(q) == -1){//不为满

q->queArr[q->head] = ele;

//重置队尾
q->tail = (q->tail+1) % (capacity);
}else{
printf("队列已满\n");
return -1;
}

return 0;
}

//出队
int DeQueueEle( myQueue *q,QueType *ele){

if(QueueEmpity(q) == -1){//不为空
*ele = q->queArr[q->head];
q->head ++;
//重置队首
q->head = (q->head+1) % (capacity);
}else{
printf("队列为空\n");
return -1;
}
return 0;
}

//获取第一元素
int GetHead(myQueue *q ,QueType *ele){
*ele = q->queArr[q->head];
return 0;
}

//统计队列元素个数
int getQueueSize(myQueue *q){

return (capacity - q->head + q->tail)%(capacity) ;
}

//遍历元素
void showQueueList(myQueue *q){

int i,size ;
size = getQueueSize(q);
for(i = q->head ; i < size ;i++){
printf("队列中的元素:%d\n",q->queArr[i]);

}

}
测试:

int main(void){

int ret = 0;
int size = 0;

myQueue *que ;
que = (myQueue *)malloc(sizeof(myQueue));
//que->head = que->tail=0;
InitQueue(que);

EnQueueEle(que , 1);
printf("增加一个元素\n");
size = getQueueSize(que);
printf("队列元素个数为[%d]\n",size);
showQueueList(que);
free(que);
return 0;
}


结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息