数据结构基础五-----《线性结构的两种常见应用之一 队列》

来源:互联网 发布:主流数据库 对比 编辑:程序博客网 时间:2024/05/19 18:47

线性结构的两种常见应用之二  队列


1.定义:

     一种可以实现“先进先出”的存储结构。只能在一端插入,另一端进行删除的存储结构。


2.分类:

a)链式队列——用链表实现


b)静态队列【数组队列】——用数组实现
         静态队列通常都必须是循环队列


3.循环队列的讲解:

① 静态队列为什么必须是循环队列
       a) 非空队列中  front永远指向队列头元素,而rear永远指向队列尾元素的下一个位置。

            普通队列参数front和rear,只增不减,导致内存浪费。
② 循环队列需要几个参数来确定
              需要两个参数来确定

                     front

                     rear      

③ 循环队列各个参数的含义
a)    两个参数不同场合有不同的含义
                   1). 队列初始化
                            front和rear的值都是零
                   2). 队列非空
                            front代表的是队列的第一个元素
                            rear代表的是队列的最后一个有效元素的下一个元素
                   3). 队列空
                            front和rear的值相等,但不一定是零

④ 循环队列入队伪算法讲解



两步完成:

   第一步:先将值 存入r所代表的位置,然后r向后移一个位置
   第二步:错误的写法:r= r+1
                  正确的写法:r = (r+1)%数组的长度
⑤ 循环队列出队伪算法讲解    
                    f = (f+1)%数组的长度
⑥ 如何判断循环队列是否为空
             如果front与rear的值相等,
             则该队列一定为空
⑦ 如何判断循环队列已满



4.预备知识:

front的值可能比rear大,也完全有可能比rear小当然有可能两者相等。
两种方式:
1:多增加一个标识参数,用来存放数组的长度,如果
2:少用一个元素,如果r 和f紧挨着,则队列已满。 如果front == (rear + 1)%数组的长度,则循环队列已满(最常用)


5.队列的具体应用:

        所有和时间有关的操作都有队列的影子


6.队列算法

           入队

            出队


示例1:用程序实现循环队列的入队/出队操作

#include<stdio.h>#include<malloc.h>typedef struct Queue{int * pBase;int front;int rear;}QUEUE;void init(QUEUE *);bool en_queue(QUEUE*,int);void traverse_queue(QUEUE *);bool full_queue(QUEUE *);bool out_queue(QUEUE *,int *);bool empty_queue(QUEUE *);int main(void){QUEUE Q;init(&Q);int val;en_queue(&Q,1);en_queue(&Q,2);en_queue(&Q,3);en_queue(&Q,4);en_queue(&Q,5);en_queue(&Q,6);en_queue(&Q,7);traverse_queue(&Q);if(out_queue(&Q,&val)){printf("出队成功,出队元素是  %d\n",val);}else{printf("出队失败\n");}traverse_queue(&Q);return 0;}//对队列进行初始化void init(QUEUE * pQ){pQ->pBase = (int *)malloc(sizeof(int)* 6);pQ->front = 0;pQ->rear = 0;}//入队操作bool en_queue(QUEUE*pQ,int val){if(full_queue(pQ))return false;else{pQ->pBase[pQ->rear]  =val;  //pQ-> pBase 代表的是数组  因为这个循环队列是用数组来实现的。pQ->rear = (pQ->rear +1 )%6;return true;}}//判断队列是否满了bool full_queue(QUEUE * pQ){if( (pQ->rear +1)%6 == pQ->front)return true;elsereturn false;}//遍历输出void traverse_queue(QUEUE * pQ){int i = pQ->front;while(i != pQ->rear){printf("  %d",pQ->pBase[i]);i = (i+1)%6;}printf("\n");return;}//判断队列是否为空bool empty_queue(QUEUE *pQ){if(pQ->front == pQ->rear)return true;elsereturn false;}//出队操作bool out_queue(QUEUE * pQ,int * pVal){if(empty_queue(pQ))return false;else{* pVal = pQ->pBase[pQ->front];pQ->front = (pQ->front +1)%6;return true;}}



阅读全文
0 0
原创粉丝点击