数据结构自学——(4)队列的代码实现

#include<stdio.h>
#include<malloc.h> 

typedef struct Queue
{
	int * pBase;		//数组,数组的首地址 
	int len;			//数组长度 
	int front;			//队首 
	int rear;			//队尾 
}QUEUE;

void init_queue(QUEUE *);				//初始化 
bool en_queue(QUEUE *, int val);		//入队 
void traverse_queue(QUEUE *); 			//遍历 
bool full_queue(QUEUE *);				//是否队满 
bool out_queue(QUEUE *, int * pVal);	//出队
bool empty_queue(QUEUE *);				//是否队空 
 

int main(void)
{
	Queue Q;			//定义后还未赋值 
	int val;			//用来返回出队元素的值 
	
	
	init_queue(&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);
	
	traverse_queue(&Q);
	
	if( out_queue(&Q,&val) )
	{
		printf("出队成功,删除的值为:%d\n",val);
	}
	else{
		printf("出队失败!\n");
	}
	traverse_queue(&Q);
	
	return 0;
}

void init_queue(QUEUE * pQ)			//初始化函数 
{
	printf("请输入队列的容量:");
	scanf("%d",&pQ->len);
	//这里本来写的是 scanf("%d",pQ->len);忘了加取址符,导致输入len失败,将数值输入进数值中显然不合适 
	pQ->pBase = (int *)malloc(sizeof(int) * (pQ->len+1) );     
	//为数组分配空间,考虑到为了区分队满和队空,我们舍弃了一个元素的空间,在这里先加上 
	
	//队首队尾都指向数组下标0 
	pQ->front = 0;
	pQ->rear = 0;
}

bool en_queue(QUEUE * pQ, int val)
{
	if( full_queue(pQ) )
	{
		printf("%d入队失败!\n",val);
		return false;
	}
	else
	{
		pQ->pBase[pQ->rear] = val;
		pQ->rear = (pQ->rear + 1) % (pQ->len+1);
		
		return true;
	}
}

bool full_queue(QUEUE * pQ)
{
	if( (pQ->rear + 1) % (pQ->len+1) == pQ->front )
	/*
		判断是否满算法解析
		1.为了区分队满和队空(因为他们都可以用队尾等于队首来表示)
		  我们将牺牲数组中一个元素的空间,当队尾指针指向这个空间时(队尾指针指向最后一个有效位后一位)
		  这时候就判断循环队列已经满了,这样就可以避免队满和队空判断方式的冲突
		2.判断方式: (pQ->rear + 1)%(len + 1) == pQ->front
		  (pQ->rear + 1)%(len + 1)   //队尾加一取余数组长度,这个算法意义在于:
		  首先如果 pQ->rear + 1没有超过数组范围的话,它必然小于数组长度,经过取余求出的还是它本身
		  其次如果此时 pQ->rear恰好指向数组的最后一个元素,我们将它加一后就正好等于数组长度
		  (因为数组下标是从零开始的,最高位下标显然等于数组长度-1), 
		  因此在rear指向数组最后一个元素下标的时候,取余的结果恰好为0,rear从0重新开始
		  通过这个巧妙的算法判断,使得不管ps->rear下标为多少,我们永远都能算出它的下一位
		3.另外要注意的是,因为我们舍弃了数组中的一个元素,
		   所以实际上的数组长度应该是我们所输入的数组长度+1
	*/
	{
		return true;
	}
	else
	{
		return false;
	}
}

void traverse_queue(QUEUE * pQ)
{
	int i = pQ->front;
	
	printf("循环队列中的元素是:");
	while (i != pQ->rear)
	{
		printf("%d ",pQ->pBase[i]);
		i=(i+1) % (pQ->len+1);
	}
	printf("\n");
	
	return;
}

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];					//将要删除的值赋给pVal 
		 
		pQ->front = (pQ->front + 1) % (pQ->len + 1);
		
 		return true;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值