c语言队列笔记

队列是一种对数据的"存"和"取"受限制的线性存储结构。
与栈结构不同的是,队列的两端都"开口",要求数据只能从一端进,从另一端出,
通常,称进数据的一端为 “队尾”,出数据的一端为 “队头”,数据元素进队列的过程称为 “入队”,出队列的过程称为 “出队”。
队列的实现

队列存储结构的实现有以下两种方式:
顺序队列:在顺序表的基础上实现的队列结构;
链队列:在链表的基础上实现的队列结构;
顺序队列,即采用顺序表模拟实现的队列结构
顺序队列:队列的顺序存储结构称为顺序队列。它是运算受限的顺序表。
①和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。
②由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应置为0。

1. AddQueue(ElemType x)
——在队列的尾部插入一个新的元素x。队尾的位置由rear指出。
2. DelQueue(Q)
——删除队列的队头的元素。队头的位置由front指出。
3. EmptyQueue(Q)
——测试队列Q是否为空队。当队列为空时返回一个真值,否则返回一个假值。
4. FrontQueue(Q)
——取得队列Q的队头元素。该运算与DelQ(Q)不同,后者要修改队头元素指针。
5. SetNULL(Q)
——创建一个空队Q,这个运算与线性表置空表类似。

顺序队列:队列的顺序存储结构称为顺序队列。它是运算受限的顺序表。
①和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。
②由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应置为0。
解决“假溢出”的方法有两种:
 (1) 采用平移元素的方法,即一旦发生“假溢出”就把整个队列的元素平移到存储区的首部。平移元素的方法效率是很低的。
 (2) 将整个队列作为循环队列来处理,。这样,虽然物理上队尾在队首之前,但逻辑上队首仍然在前,作插入和删除运算时仍按"先进先出"的原则。

队列的顺序存储结构可描述为:

#define MAXSIZE 100
typedef int DATATYPE;
typedef struct tagQUEUE
{
DATATYPE elem[MAXSIZE];
   	int front, rear;	//队列头和队列尾的位置标记
}QUEUE;

顺序队列的基本操作
①入队时:将新元素插入rear所指的位置,然后将rear加1。
②出队时:删去front所指的元素,然后将front加1并返回被删元素。
注意:
①当头尾指针相等时,队列为空。
②在非空队列里,队头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。
顺序队列中的溢出现象
① "下溢"现象
 当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。
② "真上溢"现象
 当队列满时,做进队运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。
③ "假上溢"现象
  由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为"假上溢"现象。
循环队列
为充分利用向量空间,克服"假上溢"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。

拥有MAXSIZE个数组元素的数组仅能表示一个长度为MAXSIZE-1的循环队列。

循环队列满的条件:(rear + 1) % MAXSIZE == front
循环队列空的条件:rear == front
循环队列出队:front = (front + 1) % MAXSIZE
循环队列入队:rear = (rear + 1) % MAXSIZE
循环队列的长度:(MAXSIZE + rear – front)% MAXSIZE
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1024
typedef struct queue {
	int front;
	int rear;
	int *array;
	int count;
}Queue,*pQueue;
void IinitQueue(pQueue q)
{
	q->array=(int *)malloc(sizeof(int)*MAXSIZE);
	q->front = 0;
	q->rear = 0;
	q->count = 0;
}
int isFull(pQueue q)
{
	if ((q->rear + 1) % MAXSIZE == q->front)
		return 1;
	else
		return 0;
}
int isEmpty(pQueue q)
{
	if (q->rear== q->front)
		return 1;
	else
		return 0;
}
int InQueue(pQueue q, int num)
{
	if (isFull(q))
	{
		printf("队满\n");
		return 1;
	}
	q->array[q->rear] = num;
	q->rear = (q->rear + 1) % MAXSIZE;
	q->count++;
	return 0;
}
int OutQueue(pQueue q)
{
	if (isEmpty(q))
	{
		printf("对空\n");
		return 1;
	}
	q->count--;
	q->front = (q->front + 1) % MAXSIZE;
	return q->array[q->front-1];
}
int OutputQueueValue(pQueue q)
{
	int i = 0;
	if (isEmpty(q))
	{
		printf("队空\n");
		return 1;
	}
	while (i<q->count)
	{
		printf("%d\n",q->array[i]);
		i++;
	}
	return 0;
}
int main()
{
	int i = 0;
	Queue q;
	IinitQueue(&q);
	for (i = 0; i < 5; i++)
	{
		InQueue(&q, i);
	}
	OutputQueueValue(&q);
	while (!isEmpty(&q))
	{
		printf("%d\n", OutQueue(&q));
	}
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值