0521学习总结(循环队列,链式队列)

循环队列:
1、为什么要引入循环队列?
以queue[10]为例,虽然queue[9]这个位置存储了元素,如果按照顺序存储的方式来存储的话,那么再入队列就没有地方存储!
但是前面的几个空格里面是空的,比如说queue[0],queue[1]===》假溢出!


2、循环队列的操作:
1、空队列的状态:
front  = 0;
rear = 0;
2、具体的操作:
1、初始化一个空队列;
伪代码:将队头指针和队尾指针都初始化为0;
void in_queue()
{
front = 0;
rear = 0;
}
2、判断队列是否为空:和顺序存储队列的判定条件是一样的!
int empty_queue()
{
if(front == rear)
{
printf("The queue is empty!\n");
return QUEUE_EMPTY;
}
return QUEUE_NOEMPTY;
}
3、判断循环队列是否满:
本例子里面的队列的MAXSIZE = 7;
满队列状态:rear = 1;front = 2;
判断条件满队列的条件:(rear + 1)%MAXSIZE == front;

总结:
对于queue[5]队列,实际上满队列的状态queue[0]、queue[1]、queue[2]、queue[3]、queue[4]都应该存放数据;
但是如果是这样的话,那么rear = front;和空队列的判定条件相冲突!
===》解决方案?
1、加上flag!  if(flag == 0 && front == rear)
 {
空!
 }
 if(flag == 1 && front == rear)
 {
满队列!
 }
2、空一格不存储;
满队列时。rear != front;

满队列分为两种状态:
1、rear > front;
rear + 1 = MAXSIZE;
2、rear < front;
rear + 1 == front;

根据分析判断,对于上面的两种状态:(rear + 1)%MAXSIZE == front;

代码:
int full_queue()
{
if((rear + 1)%MAXSIZE == front)
{
printf("The queue is full!\n");
return QUEUE_FULL;
}
return QUEUE_NOFULL;
}
4、入队列:
1、判断是否满队列;
2、将要存储的元素赋值进去:和顺序存储队列是一样的分析方式,rear往后移动一个,再把元素赋值进入!
rear+1;
循环队列:
1、rear > front;
1、rear = rear + 1; //rear = 3;
2、特殊的是,原来rear指向队列的最后一个元素,此时要是入队列:rear ==>0
rear = rear + 1; 错的!
2、rear < front;
rear = rear + 1;

判断方式:
rear = (rear + 1) % MAXSIZE;
代码:
int in_queue(int num)
{
if(full_queue() == QUEUE_FULL)
{
return IN_NO;
}
rear = (rear + 1) % MAXSIZE;
queue[rear] = num;
return IN_OK;
}

5、出队列:
1、判读队列对否为空;
2、出队列操作;和顺序存储队列是一样的分析方式,front往后移动一个,再把元素取出来!

判断方式:
front = (front + 1) % MAXSIZE;
代码:


队列的链式存储:
比较:
1、循环队列和不是循环队列的比较:判定条件,存储模式,代码的异同;
2、链栈和链队列:

数组:===》结构体;
 ===》链表;
 ===》栈:对数组操作;===》栈的链式存储;
 ===》队列:          ===》队列的链式存储;
 
链表的队列式操作:理解为在链表的尾节点插入,在链表的第一个结点处删除!

1、结点类型:
struct node
{
int data; //保存的数据;
struct node *pNext; //指向的下一个结点的地址;
};
struct Queue
{
struct node *front; //指向链表的头结点;
struct node *rear; //指向链表的尾节点;
};
2、初始化:将front和rear都指向NULL;
void init_queue(struct Queue *q)
{
q->front = NULL;
q->rear = NULL;
}
3、判断是否是否为空:
判断rear或者front是否空;
int empty_queue(struct Queue *q)
{
if(q->front ==NULL) //if(q->rear == NULL)
{
printf("The queue is empty");
return QUEUE_EMPTY;
}
return QUEUE_NOEMPTY;
}

4、判断是否为满:不需要判断!
5、入队列:
伪代码:
1、申请一个结点大小的堆空间;
2、判断一下申请的堆空间是否成功;
3、给申请的结点赋值;
4、将新申请的结点插入到链表的最后一个结点的后面;
5、将rear指向新申请的结点;
代码:
int in_queue(struct Queue *q,int num)
{
struct node *p = (struct node *)malloc(sizeof(sizeof(struct node )));
if(p == NULL)
{
printf("malloc error!\n");
return IN_NO;
}
p->data = num;
p->pNext = NULL;
//4
//判断链表里面没有结点,将p作为头结点;
if(q->rear == NULL)
{
q->front = p;
q->rear = p;
}
else
{
q->rear->pNext = p; //q->rear指向了链表的尾节点;
q->rear = p;
return IN_OK;
}
}
6、出队列:
伪代码:

代码:
int out_queue(struct Queue *q,int *num)
{
if(empty_queue(q) == QUEUE_EMPTY)
{
return OUT_NO;
}
struct node *p = q->front;
*num = p->data;
q->front = p->pNext; //q->front = q->front->pNext;
//只有最后一个结点要删除;
if(q->front == NULL)
{
q->rear = NULL;
}

free(p);
p = NULL;
return OUT_OK;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值