数据结构--队列(循环,链式)

队列的定义

  • 队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表
  • 队列是一种先进先出的线性表(FIFO)
  • 允许插入的一端称为队尾,允许删除的一端称为队头
  • 线性表有顺序存储和链式存储,队列作为一种特殊的线性表,也同样存在这两种存储方式

循环队列

  • 队列顺序存储有很多不足,我们用两个指针对位置进行标记,front指向第一个元素的位置,rear指向最后一个元素的下一个位置
  • 我们添加元素时,就是在队尾直接添加,不需要移动任何元素,rear++即可,但如果要删除时 ,我们就把front++,这样的话顺序存储的队列在进行有限次的删除后就不能用了
  • 但是如果后面满了,我们也可以从前面存储,也就是头尾相接的循环
  • 我们把队列这种头尾相接的顺序存储结构称为循环队列

循环队列讲解

  1. 循环队列两个参数的意义
    1)队列初始化
    front和rear值都是零
    2)队列非空
    front代表的是队列的第一个元素
    rear代表的是队列的最后一个有效元素的后一位
    3)队列空
    front和rear的值相等,但不一定是零
  2. 入队
    循环队列入队即将值存入r所代表的位置
    rear=(rear+1)%数组的长度
  3. 出队
    front=(front+1)%数组的长度
  4. 判断循环队列是否为空
    front和rear的值相等,则该队列就一定为空
  5. 如何判断队列已满?
    ①设置一个变量来记录循环队列一共存了几个值?但我们进行出队及入队操作的时候,都要对这个变量进行修改比较麻烦
    ②少用一个循环队列的元素及我们认为还剩一个空没有存入数字的时候,这个队列就是满的,这样也没有特别浪费空间,如果这个数组是1万的话。这个浪费可以忽略不计,那么判断方法就是如果front和rear的值紧挨着队列已满
    即:(rear+1)%数组的长度==front

上面的所以式子之所以这样写是因为rear可能在front的前面,也可能在front的后面

  • 这里我把队列的长度n定义为全局变量,你也可以作为形参传入每个函数中
#include
#include
#include

typedef struct Queue{
	int *pBase;
	int front;
	int rear;
}QUEUE;

int n;
void init(QUEUE *);
bool en_queue(QUEUE *,int val);
void traverse_queue(QUEUE *);
bool full_queue(QUEUE *);
bool out_queue(QUEUE *,int *);
bool empty_queue(QUEUE *); 
int length_queue(QUEUE);

int main(){
	int l;
	int val;
	QUEUE Q;
	printf("请输入循环队列的大小:");
	scanf("%d",&n); 
	init(&Q);
	
	en_queue(&Q,1);
	en_queue(&Q,2);
	en_queue(&Q,3);
	en_queue(&Q,4);
	en_queue(&Q,5);
	en_queue(&Q,6);
	en_queue(&Q,7);
	en_queue(&Q,8);
	
	traverse_queue(&Q);
	
	if(out_queue(&Q,&val)){
		printf("出队成功!出队的元素是:%d\n",val);
	}
	else{
		printf("出队失败!\n");
	}
	traverse_queue(&Q);
	l=length_queue(Q);
	printf("队列的长度是:%d\n",l);
	return 0;
}

void init(QUEUE *pQ){
	pQ->pBase=(int *)malloc(sizeof(int)*n);
	pQ->front=0;
	pQ->rear=0;
}

bool full_queue(QUEUE *pQ){
	if((pQ->rear+1)%n==pQ->front)
		return true;
	else
		return false;
}

bool en_queue(QUEUE *pQ,int val){
	if(full_queue(pQ)){
		return false;
	}
	else{
		pQ->pBase[pQ->rear]=val;
		pQ->rear=(pQ->rear+1)%n;
		return true;
	}
}

void traverse_queue(QUEUE *pQ){
	int i;
	i=pQ->front;
	
	while(i!=pQ->rear){
		printf("%d ",pQ->pBase[i]);
		i=(i+1)%n;
	}
	printf("\n");
}

bool empty_queue(QUEUE *pQ){
	if(pQ->front==pQ->rear)
		return true;
	else
		return false;
}

bool out_queue(QUEUE *pQ,int *pVal){
	if(empty_queue(pQ)){
		return false;
	}
	else{
		*pVal=pQ->pBase[pQ->front];
		pQ->front=(pQ->front+1)%n;
		
		return true;
	}
}

int length_queue(QUEUE pQ){
	int l=(pQ.rear-pQ.front+n)%n;
	return l;
}

链式队列

  • 简略代详细可见
    https://blog.csdn.net/weixin_45461859/article/details/103724181

你可能感兴趣的:(数据结构--队列(循环,链式))