五.学习数据结构之队列

1.队列的定义

一种可是实现“先进先出”的存储结构(像是火车站买票一样,后面添加,前面删除)

2.队列的分类

链式队列:用链表实现
静态队列:用数组实现(静态队列通常都必须是循环队列,为了减少内存浪费)

3.循环队列的讲解

3.1静态队列为什么必须是循环队列?
因为如果是普通的数组,当增加,删除元素(入队,出队)的时候rear和front都是往上移动,这样的话下面的空间就不能利用了,浪费空间
附图说明:
循环队列
3.2循环队列需要几个参数来确定 及其含义
需要2个参数来确定
front
rear
3.3 循环队列各个参数的含义
2个参数不同场合不同的含义?
1)队列初始化
front和rear的值都是零
2)队列非空
front代表队列的第一个元素
rear代表了最后一个有效元素的下一个元素
3)队列空
front和rear的值相等,但是不一定是零

4.循环队列算法

4.1循环队列入队伪算法
两步完成:
1)将值存入r所代表的位置
2)将r后移,正确写法是 rear = (rear+1)%数组长度
错误写法:rear=rear+1;

bool en_queue(QUEUE *pQ,int val)
{
    if (full_queue(pQ))
        return false;
    else
    {
        pQ->pBase[pQ->rear] = val;
        pQ->rear = (pQ->rear + 1) % 6;
        return true;
    }
}

4.2循环队列出队伪算法讲解
front = (front+1) % 数组长度

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;
    }
}

4.3如何判断循环队列是否为空
如果front与rear的值相等,
则队列一定为空

bool empty_queue(QUEUE * pQ)
{
    if (pQ->front == pQ->rear)
        return true;
    else
        return false;
}

4.4如何判断循环队列是否已满
预备知识:
front的值和rear的值没有规律,
即可以大,小,等。
两种方式:
1、多增加一个表标识的参数
2、少用一个队列中的元素(才一个,不影响的)
通常使用第二种方法
如果r和f的值紧挨着,则队列已满
用C语言伪算法表示就是:
if( (r+1)%数组长度 == f )
已满
else
不满

bool full_queue(QUEUE * pQ)
{
    if ((pQ->rear) + 1 == pQ->front)
        return true;
    else
        return false;
}

附图讲解:
判断队列 满
注意:这里有些错误,第5个元素应该为空,循环队列中为了好判断队列已满这种情况,会浪费掉一个空间,所以这里的f值去掉就正确了,所以说,一般初始化了m个数组大小空间,有用的只有m-1个。
4.5队列的初始化,主函数,遍历

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct Queue {
    int * pBase;//假设的存储的是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()
{
    QUEUE Q;
    int val;
    init(&Q);//没有初始化编译时没有问题,但是运行时会出现问题
    /*en_queue(&Q, 1);
    en_queue(&Q, 2);
    en_queue(&Q, 3);
    en_queue(&Q, 4);
    en_queue(&Q, 5);
    traverse_queue(&Q);*/
    if (out_queue(&Q, &val))
        printf("出队的值为:%d\n", val);
    else
        printf("出队失败!\n");
    //traverse_queue(&Q);
    system("pause");
    return 0;
}

void init(QUEUE * pQ)//初始化一般不要返回值
{
    pQ->pBase = (int*)malloc(sizeof(int) * 6);
    pQ->front = pQ->rear = 0;
}
void traverse_queue(QUEUE *pQ)
{   
    int i=pQ->front;
    for (i;i != pQ->rear;i=(i+1)%6)
    {
        printf("%d,", pQ->pBase[i]);
    }//这跟下面的语句相同效果
    /*while (i != pQ->rear)
    {
        printf("%d,", pQ->pBase[i]);
        i = (i + 1) % 6;
    }*/
    printf("\n");
    return;
}

5.队列的具体应用:

所有和事件有关的操作都有队列的影子。
(例如操作系统认为先进来的先处理)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值