"队列"学习

首先是简单队列,也不多说了

image

使用数组结构创建队列:

image

队列定义代码:

#include<stdio.h>

#define MAX_SIZE 10

int queue[MAX_SIZE];

int rear = -1;
int front = -1;

队列操作代码:

int InQueue(int value)
{
	if(rear >= MAX_SIZE)
		return 0;
	rear ++;
	queue[rear] = value;
	return 1;
}

int OutQueue(int *value)
{
	if(front == rear)
		return 0;
	front ++;
	*value = queue[front];
	return 1;
}

测试代码:

void main()
{
	int temp;

	while(1)
	{
		printf("1:存入;2:读取;+》:");
		scanf("%d",&temp);
		//清空临时缓冲区
		fflush(stdin);
		if(temp == 1)
		{
			printf("请输入要存入的值:");
			scanf("%d",&temp);
			fflush(stdin);
			if(InQueue(temp) == 1)
				printf("插入队列成功!\n");
			else
				printf("队列已满!\n");
		}else if(temp == 2){
			//取数据
			if(OutQueue(&temp))
			{
				printf("读取队列值为:%d\n",temp);
			}else
				printf("队列为空\n");
		}else
			break;
	}
}

 

 

接着介绍下循环队列:

image

上面的状态是先插入4个元素,然后全部取出,再插入5个元素的状态。这时候单向队列已经满了。

当队尾达到边界的时候,可以发现队列已经不能再存入数据了,然而队首还有一些空的区域。

为了弥补单队列的这个缺点,我们可以利用循环队列来实现重复利用这些空闲空间。

image

首先将队尾移到数据区域的头部,并且插入数据,那么空闲的区域又可以重复使用了。

这里的插入队列函数写作:

int InQueue(int value)
{
	//判断队满
	//1.队头一个数据都没取,且队尾到了边界
	//2.队尾已经反过来(队头已经取过数据)队尾下一个为队头
	//事实上这里浪费了一个空间,因为我们在出数据的时候还要判断一个队空
	//队头一直在取,去最后一个的时候队头与队尾相等,作为队空的条件
	if(front == -1 && rear == MAX_SIZE - 1 || rear + 1 == front)
		return 0;
	rear++;
	if(rear == MAX_SIZE) rear = 0;
	queue[rear] = value;
	return 1;
}

下面是出队函数:


int OutQueue(int *value)
{
	if(rear == front)
		return 0;
	front++;
	if(front == MAX_SIZE) front = 0;
	*value = queue[front];
	return 1;

}

可以看到思成在这里充分考虑了两种情况,普遍情况是队尾在队首前面一位的时候,这时候不能再插入了,还有一种特殊情况会使队尾在队首前面, 那就是队尾在最后一位而队首刚好在数据域第一个的时候,条件中也排除了这种情况。(如下图)

image

还有一种思路,就是《严版数据结构里的》,更加简洁,将这两种情况结合起来考虑了。

int InQueue(int value)
{
	//if(front == -1 && rear == MAX_SIZE - 1 || rear + 1 == front)
	if((rear+1) % MAX_SIZE == front)
		return 0;
	//rear++;
	//if(rear == MAX_SIZE) rear = 0;
	rear = (rear + 1) % MAX_SIZE;
	queue[rear] = value;
	return 1;
}

出队列也可以相应的改成:

int OutQueue(int *value)
{
	if(rear == front)
		return 0;
	//front++;
	//if(front == MAX_SIZE) front = 0;
	front = (front + 1) % MAX_SIZE;
	*value = queue[front];
	return 1;

}

队列还可以通过链表的存储方式来表示(链式存储):

#include<stdio.h>
#include<stdlib.h>

typedef struct _queue_node
{
	int data;
	struct _queue_node * next;
}QUEUE;

QUEUE * rear = NULL;
QUEUE * front = NULL;

int InQueue(int value)
{
	QUEUE * q = (QUEUE *)malloc(sizeof(QUEUE));
	if(q == NULL) return 0;
	q->data = value;
	q->next = NULL;
	if(front == NULL)
		front = q;
	else
		rear->next = q;
	rear = q;
	return 1;
}

int OutQueue(int *value)
{
	QUEUE * p = NULL;
	if(front == NULL)
		return 0;
	p = front;
	front = front->next;
	*value = p->data;
	free(p);
	return 1;
}
posted @ 2012-01-30 21:31  Ю詺菛╀時代  阅读(295)  评论(1编辑  收藏  举报