感谢:点击收听
1 基本知识点
1、允许删除的一端称为队头(front)
2、允许插入的一端称为队尾(rear)
3、当队列中没有元素时称为空队列
4、顺序队列:
1 使用顺序表来实现队列
2 两个指针分别指向队列的前端和尾端
**3 如果队列的大小为MaxSize个,那么元素的下标范围从0到MaxSize-1**
4 假设队头指针front指向队头元素的前一个位置,队尾指针rear指向队尾元素
顺序队列存在“假上溢”现象:
由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。
当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。
5、循环队列
1 满队列条件:Q.rear = Q.front;
2 空队列条件:Q.rear = Q.front;
如何区分?
区分队列是满还是空:
1 牺牲一个存储空间(front与rear是相邻的而非相等的)
2 引入一个标志变量flag区别空和不空
3 使用计数器count
如果选择牺牲一个空间的方法,那么满队列的判断条件为:
(rear+1)%MaxSize == front
队列为空的条件依然是:
front == rear
入队为:
rear = (rear+1)%MaxSize
出队为:
front = (front+1)%MaxSize
获取队列中元素的个数:
(rear-front+MaxSize)%MaxSize
6、链队列(使用单链表来实现队列)
1 使用无头结点的单链表表示队列
2 表头为队头,表尾为队尾
3 设置头尾指针,方便对表的两端进行操作
初始时:front = NULL;rear = NULL;
链队列的基本操作:
**1 入队:**
if(rear == NULL)//原来的队列就是空的
front = rear = newnode;//入队元素不但是队首也是队尾
else{
rear->next = newnode;//在队尾入队
rear = rear->next;//修改队尾指针
}
**2 出队:**
需要考虑队列是否为空、队列是否只有一个元素
if(队列为空)
退出
else
队列非空
那么需要
node* p = front;
value = front->data;//保存队首元素
front = front->next;//在队首出队
free(p);
//如果原来只有一个元素,那么出队之后为空
if(front == NULL) rear = NULL;//修改队尾指针
return value;
2 典型题目
注意:数组A的长度为m+1
注意:队列中只有一个元素的情况
3 算法题目
1、
使用两个栈来模拟队列
2、
入队:
Queue Queue_in(Queue Q,int e){
//如果队列不为空,并且rear等于front
if((Q.tag == 1)&&(Q.rear == Q.front)){
//打印队列已满
printf("队列已满\n");
}else{
//入队
Q.rear = (Q.rear+1)%m;
Q.data[Q.rear] = e;
if(Q.tag == 0)
Q.tag = 1;//队列已经不为空
}
return Q;
}
出队:
ElemType Queue_out(Queue Q){
if(Q.tag == 0)
printf("队列为空\n");
//退出
else{
Q.front = (Q.front+1)%m;
e = Q.data[Q.front];
if(Q.front == Q.rear)
Q.tag = 0;//空队列
}
return e;
}
3、
入队:
Queue Queue_in(Queue Q,int e){
//表示队满
if(Q.length == m)
return 0;
else{
Q.rear = (Q.rear+1)%m;
Q.data[Q.rear] = e;
Q.length++;
}
return Q;
}
出队:
ElemType Queue_out(Queue Q){
if(Q.length == 0)//队列为空
return 0;
else{
int front = (Q.rear-Q.length+1+m)%m;//获取队头元素
Q.length--;
return Q.data[Q.front];
}
}