数据结构基础与算法图解(4)—— 队列

4. 队列

队列是限定插入在表尾和删除在表头进行的线性表。

 ADT Queue {
    数据对象:
      D={ai | ai∈ElemSet, i=1,2,...,n, n≥0}
    数据关系:
      R1={ <a i-1,ai > | ai-1, ai ∈D, i=2,...,n}  //约定其中a1 端为队列头, an 端为队列尾
    基本操作:
      InitQueue(&Q)                  DestroyQueue(&Q)
      QueueEmpty(Q)                QueueLength(Q)
      GetHead(Q, &e)                ClearQueue(&Q)
      EnQueue(&Q, e)               DeQueue(&Q, &e)
      QueueTravers(Q, visit())
} ADT Queue

InitQueue(&Q)//操作结果:构造一个空队列Q。
    
DestroyQueue(&Q)//初始条件:队列Q已存在。操作结果:队列Q被销毁,不再存在。

ClearQueue(&Q)//初始条件:队列Q已存在。操作结果:将Q清为空队列。

4.1 队列的链式实现

在这里插入图片描述
介绍队列的链表实现方式

typedef struct QNode { // 结点类型
   QElemType      data;
   struct QNode  *next;
} QNode, *QueuePtr;

typedef struct { // 链队列类型
    QueuePtr  front;  // 队头指针
    QueuePtr  rear;   // 队尾指针
} LinkQueue;

//链队列的初始化

Status InitQueue(LinkQueue &Q){
    //构造一个空队列Q
    Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
    if(!Q.front)exit(OVERFLOW);//存储分配失败
    Q.front->next=NULL;
    return OK;
}


//链队列的删除
Status DeQueue(LinkQueue &Q, QElemType &e){
    //若队列不为空,则删除Q的队头元素
    //用e返回其值,并返回OK,否则返回ERROR
    if(Q.front==Q.rear)return ERROR;
    p=Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)Q.rear=Q.front;
    free(p); return OK;
}

4.2 队列的顺序实现

在这里插入图片描述

#define MAXQSIZE  100  //最大队列长度
  typedef struct {
    QElemType  *base;  // 动态分配存储空间
    int  front;     // 头指针,若队列不空,指向队列头元素
    int  rear;      // 尾指针,若队列不空,指向队列尾元素的下一个位置
  } SqQueue;


//循环队列的插入
Status EnQueue (SqQueue &Q, ElemType e) {   // 插入元素e为Q的新的队尾元素
    if ((Q.rear+1) % MAXQSIZE == Q.front) 
        return ERROR; //队列满
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear+1) % MAXQSIZE;
    return OK;
}
//循环队列的删除
Status DeQueue (SqQueue &Q, ElemType &e) {  // 若队列不空,则删除Q的队头元素,
   // 用e返回其值,并返回OK;  否则返回ERROR
    if (Q.front == Q.rear)  return ERROR;
    e = Q.base[Q.front];
    Q.front = (Q.front+1) % MAXQSIZE;
    return OK;
}
//循环队列的长度

4.2.1 例题

1.循环队列存储在数组A[0…9]中,其头、尾指针分别是front=3和rear=1,则队列中的元素个数为__8___。

  1. 设数组A[m]作为循环队列sq的存储空间,front为队头指针,rear为队尾指针,则执行出队操作时修改指针的语句是(A)。
    sq.front=( sq.front+1)%m
    sq.front=( sq.front+1)%(m+1 )
    sq.rear=( sq.rear+1)%m
    sq.rear=( sq.rear+1)%(m+1)

4.2.2 斐波那契序列

试利用循环队列编写求k阶斐波那契序列中前n+1项(f0, f1 , f2 ,… fn )的算法,要求满足fn ≤max而fn+1 >max ,其中max为某个约定的常数。f0=0 , f1=0 , …, fk-2=0 , fk-1=1, fn = fn-1 + fn-2 +…+ fn-k (n=k,k+1,…)

算法思路:用数组f[i]存放斐波那契数列的第i项,循环队列 cq[0…k-1] 存放f(n-k)到f(n-1)的值。所以斐波那契额的第K项=循环队列中所有元素之和。

void fb(int k)
{ int i,j;
for(i=0;i<=k-2;i++)  { f[i]=0 ; cq.elem[i]=0 ; }        //为前k-1个元素赋初值0,并放入队列cq
   cq.elem[k-1]=f[k-1]=1;    //为第k个元素赋值,并放入队列cq
  cq.rear=k-1;   n=k;
  while(cq.elem[cq. rear]<max)    //利用循环队列依次求f[n]
       {f[n]=0;
         for(j=0;j<k;j++)  f[n]=f[n]+cq.elem[j];
         cq.rear=(cq.rear +1) % k;
         cq.elem[cq.rear]=f[n];
         n++;
       }                       //利用循环队列依次求f[n]
   if(cq.elem[cq.rear]>max)  n=n-2; else n=n-1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zyw2002

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值