数据结构-------队列

队列
定义:是一种操作受限的线性表,只允许在表的一端进行插入,而在表的一端进行删除。
特性:先进先出(FIFO)
队头:允许删除的一端,又称队首。
队尾:允许插入的一端。
顺序存储
队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并设置两个指针:队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置(可以有不同的定义)。
循环队列
将存储队列元素的表从逻辑上视为一个环,称为循环队列。
判空:Q.front==Q.rear
判满的三种处理方式:
	1.牺牲一个单元来区分队空和队满,入队时少用一个队列单元
        队满条件:(Q.rear+1)%MaxSize==Q.front
        队列中元素个数:(Q.rear-Q.front+MaxSize)%MaxSize
	2.类型中增设表示元素个数的数据成员。
        队空:Q.size==0
        队满:Q.size==MaxSize
	3.类型中增设tag数据成员
		队空:tag==0
		队满:tag==1
链式存储
定义:同时带有队头指针和队尾指针的单链表。头指针指向队头结点,尾指针指向队尾结点,即单链表的最后一个结点。
判空:Q.front==NULL且Q.rear==NULL
出队:首先判断队列是否为空,不空,取出队头元素,将其从链表中摘除,并让Q.front指向下一个结点(若该结点为最后一个结点,则置Q.front==Q.rear==NULL)
入队:建立一个新结点,将新结点插入到链表的尾部,并改让Q.rear指向这个新插入的结点(若原队列为空,则令Q.front也指向该结点)
特点:适合数据元素变动比较大的情形,而且不存在队列满且产生溢出的问题。
双端队列
允许两端都可以进行入队和出队操作的队列
输入受限的双端队列:一端插入,两端删除
输出受限的双端队列:一端删除,两端插入
考点:判断输出序列的合法性。
应用
  • 层次遍历二叉树
1. 根结点入队
2. 若队空,则结束遍历;否则,重复3操作
3. 队列中第一个结点出队,并访问之。若其有左孩子,则将左孩子入队,若其有右孩子,将右孩子入队。返回2操作。
  • 页面替换算法
  • 打印机问题
  • CPU分配:程序结束或用完规定的时间间隔。
大题
  1. 若希望循环队列中的元素都能得到利用,则需设置一个标志域tag,并以tag的值为0或1来区分队头指针front和队尾指针rear相同时的队列状态是空还是满。编写入队和出队算法。
//思路:进队时置tag为1,出队时置tag为0(只有入队操作可能导致队满,只有出队操作可能导致队空)。队列初始时,置tag为0,front=rear=0
//队空:Q.front==Q.rear&&Q.tag==0
//队满:Q.front==Q.rear&&Q.tag==1
//入队
int EnQueue(SqQueue &Q,ElemType x){
    if(Q.front==Q.raer&&Q.tag==1)
        return 0;
    Q.data[Q.rear]=x;
    Q.rear=(Q.rear+1)%MaxSize;
    Q.tag=1;
    return 1;
}
//出队
int DeQueue(SqQueue &Q, ElemType &x){
    if(Q.front==Q.rear&&Q.tag==0)
        return 0;
    x=Q.data[Q.front];
    Q.front=(Q.front+1)%MaxSize;
    Q.tag=0;
    return 1;
}
  1. Q是一个队列,S是一个空栈,实现将队列中的元素逆置的算法
void Inverser(Stack S,Queue Q){
    while(!QueueEmpty(Q)){
        x=DeQueue(Q);
        Push(S,x);
    }
    while(!StackEmpty(S)){
        Pop(S,x);
        EnQueue(Q,x);
    }
}
  1. 利用两个栈s1、s2来模拟一个队列
Push(S,x)元素x入栈S
Pop(S,x)S出栈并赋值给x
StackEmpty(S)判断栈是否为空
StackOverflow(S)判断栈是否为满

如何利用栈的运算实现该队列的3个运算

Enqueue将元素x入队
Dequeue出队,并将出队元素存储在x中
QueueEmpty判断队列是否为空
//对s2的出栈操作 用作出队,若s2为空,则先将s1中的所有元素送入s2
//对s1的入栈操作 用作入队,若s1满,必须先保证s2为空,才能将s1中的元素全部插入s2中
//入队
int EnQueue(Stack &s1,Stack &s2,ElemType e){
    if(!StackOverflow(s1)){
        Push(s1,e);
        return 1;
    }
    if(StackOverflow(s1)&&!StackEmpty(s2)){
        printf("队列满");
        return 0;
    }
    if(StackOverflow(s1)&&StackEmpty(s2)){
        while(!StackEmpty(s1)){
            Pop(s1,x);
            Push(s2,x);
        }
        Push(s1,e);
        return 1;
    }
}
//出队
void DeQueue(Stack &s1,Stack &s2, ElemType &x){
    if(!StackEmpty(s2))
        Pop(s2,x);
    else if(StackEmpty(s1))
        printf("队列为空");
    else{
        while(!StackEmpty(s1)){
            Pop(s1,x);
            Push(s2,x);
        }
        Pop(s2,x);
    }
}
//判空
int QueueEmpty(Stack s1,Stack s2){
    if(StackEmpty(s1)&&StackEmpty(s2))
        return 1;
    else
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一刻不学习就是15分钟

对您有用就行,别钱不钱的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值