【数据结构学习6】队列学习

时间:2022-04-10 13:39:43

1.队列的定义(queue)

队列是只允许在一端删除,一端插入的线性表。(例子:例如淘宝的在线客服,计算机到显示屏的输出等等)

循环队列的顺序储存:

typedef struct{

Qelemtypedata[MAXSIZE];

int *front;//*头指针*//

int *rear;//*尾指针,指向队尾元素的下一个位置*//

}SqQueue;


Status InitQueue(Squeue *Q){

Q->front=0;

Q->rear=0;

returnOK;

}


循环队列中求队列长度:

int QueueLength(SqQueue Q){

return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;标号1

}

标号处:长度为何时Q.rear-Q.front+QUEUESIZE

若循环队列中,front在rear前面,那么队列的长度就为:rear-front

若rear在front的前面,那么队列的长度为:QUEUESIZE-(front-rear)=rear-front+QUEUESIZE

那么通过转换通用的公式就为:(Q.rear-Q.front+MAXSIZE)%MAXSIZE(此处其实就是queuesize)

队列的入列操作,入列只能在队尾

Status EnQueue(Squeue *Q,QElemtype e){

if(Q->rear+1%MAXSIZE==Q->front) //*判断队满*//

return ERROR;

Q->data[Q->rear]=e;//*规定尾指针留空*//

Q->rear=(Q->rear+1)%MAXSIZE;//*将指针后移一位,若也就是余数为0,满了,则转到头部指针*//

returnOK;}


Status DeQueue(SqQueue *Q,Qelemtype *e){

if(Q->front==Q->rear)

return ERROR;

*e=Q->data[Q->front];

Q->front=(Q->front+1)%MAXSIZE;//*因为无论是front或者rear都是从0开始的,所以需要加1*//

return OK;}


2.链队列:||队列的链式存储结构(非循环)

typedef structQnode{

Qelemtype data;

struct Qnode *next;

}Qnode,*Queueptr;


typedef struct{

Queueptr    front;

Queueptr    rear;

}LinkQueue;    //*此处定义出头结点,并有两个指针指着*//

为什么不把front 与rear的定义放在栈的定义中:

可能是为了增加代码的可读性。


(1)初始化:

Status InitQueue(LinkQueue  &Q){

Q.front=Q.rear=(Queueptr)malloc(size(Qnode));

if(!Q.front)exit(OVERFLOW);

Q.front->next=NULL;  //*其实就是指着自己*//

return ok;

}

(2)插入:

Status Enqueue(LinkQueue Q,QElemType e){

QueuePtr s=(QueuePtr)malloc(sizeofQnode);  //*此处的s即是front 与rear指针的结构体,也就是两个指针*//

if(!s) exit(OVERFLOW);

s->data=e;

s->next=NULL;  //*因为是尾指针,所以应该在尾指针处置为NULL*//

Q.rear->next=s;  //*关于此处,因为rear指针前的q为,*//

Q.rear=s;

return ok;

}

(3)出队

提示:有一个头结点

Status DeQueue(LinkQueueQ,QElemType &e){

QueuePtr ep;

if(Q.rear==Q.front) //*条件应该是尾指针,头指针指向同一个地方,也就是头结点时*//

return ERROR;

p=Q.rear->next;

Q.front->next=p->next;

if(Q.rear==p) //*因为不是循环队列,所以当删除尾列时应该*//

Q.rear=Q->front;

free(p);

return  ok;

}


3.循环队列(运用尾指针)

存储结构:

typedef  CQqueue{

Qelemtype data;

CQqueue   *next;

}CQqueue,*CQlink;


CQlink InitCiqueue(CQlink Q){

 Q=(CQlink)malloc(sizeof(CQnode));

 Q->next=Q; //*形成循环*//

}


CQlink  EnCIqueue(CQlink Q,int &e){

p=(CQlink)malloc(sizeof(CQqueue));

if(!p) exit(ERROR);

p->data=e;

p->next=rear;

rear->next=p;

rear=p;

return ok;

}


CQlink  DeCIqueue(CQlink Q,int &e){

if(rear->next=rear)

exit(ERROR);

p=rear->next->next;

rear->next->next=p->next;

if(rear==p)

rear=rear->next; //*因为rear还是指向p,虽然循环结构还是完全*//

free(p);

return ok;

}


void display(CQlink Q){

CQlink p;

p=rear->next->next;

while(p!=rear->next){

printf("%4d",p->data);

p=p->next;

}}


总结:

队列这单元中可能相对于前面会不够熟悉,对于名词的记忆还需要我去还原。

栈:stack 队列:queue

栈:顺序栈,链栈

队列:顺序队列,循环队列,链队列,循环链队列