数据结构论坛

首页 » 分类 » 问答 » 聊聊数据结构队列之顺序存储
TUhjnbcbe - 2023/7/15 20:46:00
2023治疗白癜风最好的药哪里能买到 http://m.39.net/pf/bdfyy/bdfyw/

今天我们来聊聊队列这种数据结构。

队列是一种只允许在一端插入数据,在另一端删除数据的线性表,插入数据的一端称作队尾,删除数据的一端称作队头。队列是一种先进先出的数据结构,也就是FIFO结构。关于队列,生活中有很多例子可以加深我们对它的理解。比如我们排队买饭,排在前面的人会先买到饭,然后离开队伍,自己找座位坐下吃饭。后面来到的人只能排在队伍的后面等待着买饭。每当排在最前面的人打好了饭,大家就都会向前移动一个位置。

既然我们已经有了普通的线性表,干嘛又搞出个队列这种结构呢?其实主要是因为在某些场景使用队列会更加符合我们的需求。比如网上购票,先提交订单的用户应该优先获得购票权,后面下单的用户就得先排队等着。这种情形,就适合用队列这种结构来存储数据,先来的先处理。

线性表有顺序结构和链式结构之分,队列作为特殊的线性表,也有这两种存储方式,我们先来看看队列的顺序存储结构。

队列的顺序存储结构和线性表的表示法一致,只不过在对顺序队列操作时,删除元素只能从队头删除,添加元素只能从队尾添加。我们在删除元素时,可以将后面的元素都依次往前移动一个位置,但是这样子在性能上会有些低。其实我们如果能够确定哪些空间是闲置的,那就没有必要每次删除元素都把元素往前移动了。基于此想法,就有了循环队列(这里是指顺序存储的循环队列,链式结构中也可以有循环队列)。

我们来定义一下循环队列的顺序存储结构:

typedefstructSqQueue{

intdata[SIZE];

intfront;//用于表示队头所在的位置

intrear;//用于表示队尾所在的位置

}SqQueue;

在使用某种数据结构时,我们一定要先对数据结构内的元素进行初始化操作,然后才能进行一些增删改查的操作。当我们创建队列时,默认使队头和队尾都指向数组第一个位置,也就是下标为0的地方。

StatusinitQueue(SqQueue*q){

q-front=0;

q-rear=0;

returnOK;

}

元素入队的代码如下:

StatusenQueue(SqQueue*q,inte){

//队列满了

if((q-rear+1)%SIZE==q-front){

returnERROR;

}

q-data[q-rear]=e;

q-rear=(q-rear+1)%SIZE;

returnOK;

}

元素出队的代码如下:

StatusdeQueue(SqQueue*q,int*e){

//队列为空

if(q-front==q-rear){

returnERROR;

}

e=q-data[q-front];

q-front=(q-front+1)%SIZE;

returnOK;

}

另外,在我们计算循环队列的长度时,我们可以使用以下公式:

(q-rear-q-front+SIZE)%SIZE

循环队列相对于普通的顺序队列,避免了元素出队时移动元素的麻烦,但是顺序存储结构都可能会面临存储空间不够的问题,这种情况下,我们就要考虑使用链式存储结构了,我们再对此进行讲解。

1
查看完整版本: 聊聊数据结构队列之顺序存储