队列的实现

这篇博客介绍了队列的两种实现方式,包括链表和数组。在链表实现中,作者选择不使用头结点,并提供了具体的实现代码。对于数组实现,采用了循环队列的概念,预留一个空间作为满标志。测试结果显示实现正确。
摘要由CSDN通过智能技术生成

队列的实现

队列实现跟栈相似,有两种实现方式,一种是用链表实现,一种使用数组实现。为了使这两种实现方法具有相同的函数接口,将函数的原型声明放到queue.h文件中。

编译环境:Visual Studio 2010

fatal.h用于定义错误处理方法

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

#define FatalError(str) fprintf(stderr, "%s\n", str),exit(1)
queue.h用于声明队列的函数原型
#ifndef QUEUE_H
#define QUEUE_H

typedef int ElementType;
struct QueueRecord;
typedef struct QueueRecord *Queue;

Queue CreateQueue(void);
void DestoryQueue(Queue Q);
void ClearQueue(Queue Q);
int QueueLength(Queue Q);
int IsEmpty(Queue Q);
int IsFull(Queue Q);
ElementType Head(Queue Q);
ElementType Dequeue(Queue Q);
void Enqueue(ElementType X, Queue Q);

#endif
1. 队列的链式实现

链式实现可以有头结点也可以没有头节点,我在这里的实现方式是没有头节点的。如下图所示



queue.c队列的具体实现

#include "fatal.h"
#include "queue.h"

struct Node
{
	ElementType Data;
	struct Node *Next;
};
typedef struct Node *PtrToNode;
struct QueueRecord
{
	PtrToNode Front;//队头指针
	PtrToNode Rear; //队尾指针
};

Queue CreateQueue(void)
{
	Queue Q;

	Q = (Queue)malloc(sizeof(struct QueueRecord));
	if(Q == NULL)
		FatalError("Out of space");
	Q->Front = Q->Rear = NULL;

	return Q;
}

void DestoryQueue(Queue Q)
{
	PtrToNode TmpCell;
	while(Q->Front)
	{
		TmpCell = Q->Front->Next;
		free(Q->Front);
		Q->Front = TmpCell;
	}
	free(Q);
}

void ClearQueue(Queue Q)
{
	PtrToNode P, TmpCell;

	P = Q->Front;
	Q->Front = NULL;
	Q->Rear = Q->Front;
	while(P)
	{
		TmpCell = P->Next;
		free(P);
		P = TmpCell;
	}
}

int QueueLength(Queue  Q)
{
	int cnt = 0;
	PtrToNode P;

	P = Q->Front;
	while(P)
	{
		++cnt;
		P = P->Next;
	}
	return cnt;
}

int IsEmpty(Queue Q)
{
	return Q->Front == NULL;
}

int IsFull(Queue Q)
{
	return 0;
}

ElementType Head(Queue Q)
{
	return  IsEmpty(Q) ? -1 : Q->Front->Data;
}

ElementType Dequeue(Queue Q)
{
	ElementType X = -1;
	PtrToNode TmpCell;
	if(!IsEmpty(Q))
	{
		TmpCell = Q->Front;
		Q->Front = TmpCell->Next;
		X = TmpCell->Data;
		if(TmpCell == Q->Rear)
			Q->Rear = Q->Front;
		free(TmpCell);
	}

	return X;
}

void Enqueue(ElementType X, Queue Q)
{
	PtrToNode TmpCell;
	TmpCell = (PtrToNode)malloc(sizeof(struct Node));
	if(TmpCell == NULL)
		FatalError("Out of space");
	TmpCell->Data = X;
	TmpCell->Next = NULL;
	if(IsEmpty(Q))//如果此前为空队列,插入新元素后要求头结点的位置
	{
		Q->Front = TmpCell;
		Q->Rear = TmpCell;
	}
	else
		Q->Rear->Next = TmpCell;
	Q->Rear = TmpCell;
}
2. 队列的数组实现

预留数组中的一个空间用来判断队列是否已满。数组实现的是循环队列,如下图所示



queue.c队列的数组实现

#include "fatal.h"
#include "queue.h"

#define MAXQSIZE 100

struct QueueRecord
{
	ElementType *Array;
	int Front;
	int Rear;
	int Capacity;
};

Queue CreateQueue(void)
{
	Queue Q;

	Q = (Queue)malloc(sizeof(struct QueueRecord));
	if(Q == NULL)
		FatalError("Out of space");
	Q->Array = (ElementType *)malloc(sizeof(ElementType) * MAXQSIZE);
	if(Q->Array == NULL)
		FatalError("Out of space");
	Q->Front = 0;
	Q->Rear = 0;
	Q->Capacity = MAXQSIZE;
	return Q;
}

void DestoryQueue(Queue Q)
{
	free(Q->Array);
	free(Q);
}

void ClearQueue(Queue Q)
{
	Q->Front = Q->Rear = 0;
}

int QueueLength(Queue Q)
{
	return (Q->Rear - Q->Front + Q->Capacity) % Q->Capacity;
}

int IsEmpty(Queue Q)
{
	return Q->Front == Q->Rear;
}

int IsFull(Queue Q)
{
	return (Q->Rear + 1) % Q->Capacity == Q->Front;
}

ElementType Head(Queue Q)
{
	ElementType X;
	if(IsEmpty(Q))
		FatalError("Empty queue");
	return Q->Array[Q->Front];
}

void Enqueue(ElementType X, Queue Q)
{
	if(IsFull(Q))
		FatalError("Out of space");
	Q->Array[Q->Rear] = X;
	Q->Rear = (Q->Rear + 1) % Q->Capacity;
}

ElementType Dequeue(Queue Q)
{
	ElementType X;
	if(IsEmpty(Q))
		FatalError("Empty queue");
	X = Q->Array[Q->Front];
	Q->Front++;
	if(Q->Front == Q->Capacity)
		Q->Front = 0;
	return X;
}
queuemain.c队列测试
#include <stdio.h>
#include "queue.h"

int main(void)
{
	Queue Q;
	int i;

	Q = CreateQueue();
	for(i = 0; i < 10; i++)
		Enqueue(i, Q);
	while(!IsEmpty(Q) && i < 15)
	{
		printf("%d ", Head(Q));
		Dequeue(Q);
		++i;
	}
	putchar('\n');
	for(; i< 20; ++i)
		Enqueue(i, Q);
	while(!IsEmpty(Q))
		printf("%d ", Dequeue(Q));
	putchar('\n');
	DestoryQueue(Q);
	Q = CreateQueue();
	for(i = 20; i <= 30; i++)
		Enqueue(i, Q);
	while(!IsEmpty(Q))
		printf("%d ", Dequeue(Q));
	return 0;
}

测试结果,如下图所示


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值