26.线性表--队列

引入:

队列和栈一样都属于特殊的线性表

队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

操作:队尾进行插入操作,队头进行删除操作。

 

先入先出 的线性表

 

队列我们现实生活中经常会遇到:

比如电脑有时会进入假死状态,不动了,然后一段时间后突然把你刚做的操作全部按顺序执行一遍,这个就是多个程序需要通过一个通道输出,而按先后次序排队等待造成的。

还有银行的排队取号系统,电脑键盘的输入等都是队列的案例。

所以队列很重要,需要着重学习。

 

一.队列的顺序存储:

假如我们在窗口买票,一个人买完了出去了,后面的所有人都要跟着往前移动一个。

买票还行,但是在数组中这种效率是比较差的,为了解决这个问题,加个指针就行了,

到谁了就指向谁,没有必要非要向前移动。

同时为了避免只有一个元素时,队头和队尾重合使处理变的麻烦,所以引入两个指针,front指向队头元素,rear指针指向队尾元素。

 

typedef int datatype ;     /*定义队列中数据元素的数据类型*/

#define MAXSIZE 64                /*定义队列的容量*/

typedef struct

{       datatype data[MAXSIZE] ;      /*用数组作为队列的储存空间*/

        int      front,rear ; /*指示队头位置和队尾位置的指针*/

} sequeue,*seq_pqueue;

 

入队:(表尾插入)

但是还有一个问题,由于不需要必须从0位置出队列,头指针在不断向后走,此时

队列长度就只有5,头指针在2的位置,对列中此时有三个元素,此时再入队,尾指针就移动到数组外面了,但是队列前面还空闲着呢。

让我想起了北京的公交,每次都是前门被挤爆,后门位置还空着呢,车上明明有空间,车下的人就是上不来。(假溢出)

为了解决这种尴尬事情,就出现了循环队列。后面满了,就从头开始,让首尾相接。

什么时候说明队列满了?

front=rear说明队列满,但是front=rear也说明队列为空。

如何进行区分??

(rear+1)% queuesize == front,用这种方法来判断队列满。(浪费一个空间)

 

1.循环队列的初始化

void init_seqqueue(seq_pqueue *Q)//Q为指针的指针

{

        *Q=(seq_pqueue)malloc(sizeof(seq_queue));

        if((*Q)==NULL)

        {

                 perror("malloc");

                 exit(-1);

        }

        (*Q)->front=(*Q)->rear=MAXsize -1;

        return;

}

 

2.入队:(队尾插入)

bool in_seqqueue(datatype data,seq_pqueue q)

{

            if(is_full_seqqueue(q)){

                 return false;

            }

            q->rear=(q->rear+1)%MAXSIZE;

            q->data[q->rear]=data;

            return true;

}

3.出队:(表头删除)

bool out_seqqueue(seq_pqueue q,datatype *D)

{

            if(is_empty_seqqueue(q)){

                         return false;

            }

            q->front=(q->front+1)%MAXSIZE;

            *D=q->data[q->front];

            return true;

}

 

 

二.队列的链式存储:

只能尾进头出的单链表,和单链表操作没有什么区别。

只是多了头指针和尾指针。

1.

typedef struct linkqueuenode{

            datatype data;

            struct linkqueuenode *next;

}linkqueue_node,*linkqueue_pnode;

 

typedef struct linkqueue{

            linkqueue_pnode front,rear;

}link_queue,*link_pqueue;

 

表尾插入,表头删除。

2.插入操作(表尾插入)

bool in_linkqueue(datatype data,link_pqueue q)

{

            linkqueue_pnode  new;

            new=(linkqueue_pnode)malloc(sizeof(linkqueue_node));

            if(new==NULL)

            {

                 return false;

            }

            new->data=data;

 

            new->next=q->rear->next;

            q->rear->next=new;

 

            q->rear=q->rear->next;

 

            return true;

}

 

 

3.出队列:删除操作(表头删除)

头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表除头结点外值剩下一个元素时,则需将rear指向头结点。

 

bool out_linkqueue(link_pqueue q,datatype *D)

{

            linkqueue_pnode t;

            if(q->rear == q->front){

                 return false;

            }

            t=q->front;

            q->front =q->front->next;

            *D=q->front->data;

            free(t);

 

            return true;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值