数据结构——队列

数据结构——队列

文章目录

  • 数据结构——队列
  • 前言
  • 一、队列基本概念
  • 二、队列的基本操作
    • 1.队列的顺序存储结构
      • a.创建顺序队列代码
      • b.入队操作代码
      • c.出队操作代码
      • d.顺序队列的关键语句
    • 2.队列的链式存储结构
      • a.链式队列初始化
      • b.链式队列判断空
      • c.链式队列的入队操作
      • d.链式队列的出队操作
    • 3.循环队列
      • a.循环队列入队列操作
      • b.循环队列出队列操作
      • c.获取循环队列首元素的算法
      • d.循环队列六要素
  • 总结


前言

  1. 队列的基本概念
  2. 顺序队列
  3. 链式队列
  4. 循环队列

一、队列基本概念

1.队列的定义: 队列是一个操作受限的线性表,是一个只允许在表的一端进行插入,在表的另一端进行删除的线性表
2.队尾(rear): 允许插入的一端
3.队头(front): 允许删除的一端
4.队列的特点: 先进先出,后进后出

二、队列的基本操作

1.队列的顺序存储结构

队列的顺序存储:附设两个指针front和rear分别指示队头元素和队尾元素的下一个位置
数据结构——队列_第1张图片

a.创建顺序队列代码

Create_Qs(front,rear,max){
	elemtypr Qs[max];
	front=0;
	rear=0;
	return OK;
}

注:非空队中,头指针始终指向队列头元素的前一个元素,而尾元素始终指向队列尾元素

b.入队操作代码

指针先动,再赋值

rear++;
a[rear]=x;
或
a[++rear]=x;

c.出队操作代码

先移动指针,再赋值

front++;
x=[front];
或
x=[++front];

d.顺序队列的关键语句

1) 队列为空的条件

front==rear;

2)队列满的条件

rear=maxsize-1;

2.队列的链式存储结构

队列的链式存储:是一个同时带有队头指针和队尾指针的单链表,头指针指向队头结点,尾指针指向队尾结点

a.链式队列初始化

void InitQueue(LinkQueue &Q){
	Q.front=Q.rear=(LinkNode *)malloc(sizeof(LinkBode));	//建立头结点
	Q.front->next=NULL;		//初始为空
}


当Q.front == Q.rear ==NULL时链队列为空,通常将链队列设计一个头结点

链式队列为空条件

Q.front == Q.rear ==NULL

b.链式队列判断空

bool isEmpty(LinkQueue Q){
	if(Q.front==Q.rear)	return true;
	else return false;
}

c.链式队列的入队操作

void EnQueue(LinkQueue &Q,ElemType x){
	s=(LinkNode *)malloc(sizeof(LinkNode));
	s->data=x;	s->next=NULL;		//创建新结点,插入到链尾
	Q.rear->next=s;
	Q.rear=s;
}

d.链式队列的出队操作

bool DeQueue(LinQueue &Q,ElemType &x){
	if(Q.front==Q.rear)	return false;		//空队
	p=Q.front->next;
	x=p->data;
Q.front->next=p->next;
if(Q.rear==p)
	Q.rear=Q.front;
free(p);
}

3.循环队列

i.循环队列定义: 循环队列就是把队列的头和尾连接到一起,从而构成一个环状,实现了有空余空间就能入队的操作
ii.基本思想: 把队列设成环状,让Qs[0]接在Qs[M-1]之后,若rear+1==M,则令rear=0;
iii.实现: 利用"模"运算
数据结构——队列_第2张图片

a.循环队列入队列操作

Insert_Cq(Cq,Cq_rear,Cq_front,Cq_max,x){
	if((Cq_rear+1)%Cq_max==Cq_front)
		return ERROR;
	Cq_rear=(Cq_rear+1)%Cq_max;
	Cq[Cq_rear]=x;
	return OK;
}

b.循环队列出队列操作

Delete_Cq(Cq,Cq_rear,Cq_front,Cq_max,x){
	if(Cq_front==Cq_rear){
		printf("The circular queue is empty!");
		return Error;
	}
	Cq_front=(Cq_front+1)%Cq_max;
	x=Cq[Cq_front];
}

出队队位号: Cq_front=(Cq_front+1)%Cq_max;

c.获取循环队列首元素的算法

Head_Cq(Cq,Cq_rear,Cq_front,Cq_max,x){
	if(Cq_front == Cq_rear)		//队列为空的条件
		printf("The circular queue is emply!");
	else
		x=Cq[(Cq_front+1)%Cq_max)];
}

循环队列牺牲一个空间,存储头尾指针,如果用a[N]存储一个循环队列,则最多存储N-1个

d.循环队列六要素

  1. 入队: rear=(rear+1)%M; Qs[rear]=x; 或Qs[++rear%M]=x;
  2. 出队: front=(front+1)%M; x=Qs[front]; 或 x=Qs[++front%M];
  3. 队空: rear==front;
  4. 队满:(rear+1)%maxsize==front;
  5. 出队队位号: Cq_front=(Cq_front+1)%Cq_max;
  6. 循环队列中元素的个数: (Q.rear-Q.front+maxsize)%maxsize;

总结

队列操作核心语句总结

  1. 顺序队列入队操作: rear++; a[rear]=x; 或 a[++rear]=x;
  2. 顺序队列出队操作: front++; x=[front]; 或 x=[++front];
  3. 顺序队列为空的条件: front==rear;
  4. 顺序队列满的条件: rear=maxsize-1;
  5. 链式队列为空的条件: Q.front == Q.rear
  6. 循环队列入队: rear=(rear+1)%M; Qs[rear]=x; 或Qs[++rear%M]=x;
  7. 循环队列出队: front=(front+1)%M; x=Qs[front]; 或 x=Qs[++front%M];
  8. 循环队列队空: rear==front;
  9. 循环队列队满:(rear+1)%maxsize==front;
  10. 出队队位号: Cq_front=(Cq_front+1)%Cq_max;
  11. 循环队列中元素的个数: (Q.rear-Q.front+maxsize)%maxsize;

你可能感兴趣的:(数据结构,数据结构,算法,c语言)