队列的两种存储方式的介绍与实现

简介

队列是一种特殊的线性表,它的特殊之处在于它必须在队列的头部进行删除元素,在队列尾部插入元素。我们把队列的头部称为 对头(front),队列尾部叫做 队尾(rear)。进行删除元素位置叫队头(front),进行插入元素的位置叫在队尾(rear)。
队列的存储的数据称为队列元素,因为只能在对头进行删除的操作,队尾进行插入,先插入的先出队,所以我们可以称队列为一种 先进先出(FIFO:first in first out )的数据结构。

顺序队列

创建顺序存储结构,我们必须动态申请或静态地分配一块存储位置,设置两个指针来进行管理,分别称为对头head、队尾tail,当队头与队尾相等时
(head==tail)我们称为队空。队头指针指向队列第一个插入的元素,tail指针指向队列最后一个插入元素的下一个位置,当队列中插入一个元素时,tail+1;删除
一个元素时,head+1。
我们来看一个图:


在图中我们可以到,图1.3,当队头元素被删除后,会留下一块存储区域,它并不会再次被使用,所以会造成内存的浪费。图1.4中反应了这样一个现象,当队列所
申请的内存最后一块存储空间被占有时,当想要再插入一个新的元素时,就会产生问题,这种现象称为“假溢出”。
为了避免上述的问题,因此出现了一个新的概念:循环队列。

循环队列

循环队列,我们假想成一个循环模型,如下图所示:

当front==rear时表示队空;当循环出队列、入队列的过程中会发生一种情况,队尾在元素一的位置,队头在元素二的位置,那么头尾指针也恰好指向同一个位置,这时我们称为队满,是不是也是front==rear?



这里我用数组方式来实现循环队列:

typedef int QueType;
typedef int Status;
#define capacity 4
*采用数据存储元素,数组类型为:int
*实现队列初始化、出队列、入队列、统计队列总数、循环遍历队列元素等功能。
*/
typedef struct{

	int head;//头
	int tail;//尾
    
	QueType queArr[capacity];//队列数组
	
}myQueue; 

//队列初始化
int InitQueue(myQueue *q){
	//q = (myQueue *)malloc(sizeof(myQueue));
	q->head = q->tail = 0 ;//头和尾相等,此时为空    
	return 0;
}

//判断队列是否为空
//为空返回0,否则为-1
int QueueEmpity(myQueue *q){
	if(q->head == q->tail){//首尾相等,队列为空
		return 0;
	}
	return -1 ;
}

//判断队列是否已满
//为空返回0,否则为-1
int QueueFull(myQueue *q){
    //避免和队列为空时冲突。队列中实际还差一个位置。
	if(q->head == (q->tail+1)%(capacity)){//为满时,
		return 0;
	}
	return -1 ;
}

//入队
Status EnQueueEle(myQueue *q , QueType ele){
    
	
	if(QueueFull(q) == -1){//不为满
		
		q->queArr[q->head] = ele;
		
		//重置队尾
		q->tail = (q->tail+1) % (capacity);
	}else{
		printf("队列已满\n");
		return -1;
	}
	
	return 0;
}

//出队
int DeQueueEle( myQueue *q,QueType *ele){
	
	if(QueueEmpity(q) == -1){//不为空
		*ele = q->queArr[q->head];
		q->head ++;
        //重置队首
		q->head = (q->head+1) % (capacity);
	}else{
		printf("队列为空\n");
		return -1;
	}
	return 0;	
}

//获取第一元素
int GetHead(myQueue *q ,QueType *ele){
	*ele = q->queArr[q->head];
	return 0;
}

//统计队列元素个数
int getQueueSize(myQueue *q){
	
	return (capacity - q->head + q->tail)%(capacity) ;
}

//遍历元素
void showQueueList(myQueue *q){
	
	int i,size ;
    size = getQueueSize(q);
	for(i = q->head ; i < size ;i++){
		printf("队列中的元素:%d\n",q->queArr[i]);
		
	}

}
测试:

int main(void){
	
	int ret = 0;
	int size = 0;

    myQueue *que ;
	que = (myQueue *)malloc(sizeof(myQueue));
	//que->head = que->tail=0;
	InitQueue(que);
	

	EnQueueEle(que , 1);
	printf("增加一个元素\n");
    size = getQueueSize(que);
    printf("队列元素个数为[%d]\n",size);
	showQueueList(que);
	free(que);
	return 0;
}

结果:






  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值