队列——链表与数组实现(数据结构与算法分析C语言版)

链队列:一个链队列显然需要两个分别指向队头和队尾的指针(即头指针和尾指针)才能唯一确定。一般,为了操作方便,可以给链队列添加一个头结点,并令头指针指向头结点。由此,空的链队列的判决条件为:头指针和尾指针均指向头结点,如下图所示:


头文件:queue.h

typedef int ElementType;

#ifndef _QUEUE_LIST_
#define _QUEUE_LIST_

struct QNode;
struct Node;
typedef QNode *QNodePtr;
typedef Node *PtrToNode;
typedef PtrToNode Queue;

int IsEmpty( Queue Q );                       //判断队列是否为空Q->Rear == Q->Front;
Queue CreateQueue();                         //构造队列
void DisposeQueue( Queue Q );                //删除整个队列,回收空间
void MakeEmpty( Queue Q );                  //释放队列空间,将其置为空
void EnQueue( ElementType X, Queue Q );     //在队列尾端插入元素
ElementType Front( Queue Q );              //取出对头元素,但不删除
void Dequeue( Queue Q );                   //删除对头元素
ElementType FrontAndDequeue( Queue Q );   //
void PrintQueue( Queue Q );               //打印队列

#endif
实现文件queue.c

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

struct QNode  
{  
	ElementType Element;  
	QNodePtr Next;  
};  

struct Node 
{  
	QNodePtr Front;  
	QNodePtr Rear;  
};  


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

void MakeEmpty( Queue Q )
{
	if (Q == NULL)
	{
		printf("The queue is empty! Must use CreateQueue first!\n");
		return;
	}
	else
	{
		while(!IsEmpty(Q))
			Dequeue(Q);
	}
}

Queue CreateQueue()
{	
	//不仅要为对头(Queue)申请空间,还要为队列元素/节点(QNode)申请空间.
	Queue Q;
	Q = (Queue)malloc(sizeof(struct Node));
	if (Q == NULL)
	{
		printf("Out of space!\n");
		return NULL;
	}
	Q->Front = Q->Rear = (QNodePtr)malloc(sizeof(struct QNode));

	if (Q->Front == NULL)
	{
		printf("Out of space!\n");
		return NULL;
	}
	Q->Front->Next = NULL;
	return Q;
}

void DisposeQueue( Queue Q )
{
	while (Q->Front != NULL)
	{
		Q->Rear = Q->Front->Next;
		free(Q->Front);
		Q->Front = Q->Rear;
	}
}

void Dequeue( Queue Q )
{
	//删除链队列第一个元素
	if (!IsEmpty(Q))
	{
		QNodePtr P;
		P = Q->Front->Next;
		Q->Front->Next = P->Next;
		if (Q->Rear == P)          //判断队列中是否只有一个元素
			Q->Rear = Q->Front;
		free(P);
	}
	else
	{
		printf("The queue is empty!\n");
	}
}

void EnQueue( ElementType X, Queue Q )
{
	QNodePtr P = (QNodePtr)malloc(sizeof(struct QNode));
	if (P == NULL)
	{
		printf("Out of space!\n");
		return;
	}
	else
	{
		P->Next = NULL;
		P->Element = X;
		Q->Rear->Next = P;
		Q->Rear = P;
	}
}

ElementType Front( Queue Q )
{
	return Q->Front->Next->Element;
}

ElementType FrontAndDequeue( Queue Q )
{
	ElementType X = 0;
	if (!IsEmpty(Q))
	{
		X = Front(Q);
		Dequeue(Q);
	}
	else
	{
		printf("The queue is empty!\n");
	}
	return X;
}

void PrintQueue( Queue Q )
{
	QNodePtr P = Q->Front;
	while (P != Q->Rear)
	{
		P = P->Next;
		printf("%d\n", P->Element);
	}
}
循环队列一般是用循环数组实现,其判空条件有多种方式:其一是设一个标志位以区别队列是空还是满;其二是少用一个元素空间,约定以队列头指针在队列尾指针的下一位置上作为队列呈满状态标志。或者是如下面代码所示,为表示队列的结构体设置一个表示队列大小的size标志,若size为0,那么队列为空。
数组实现:队列头文件,queue.h

typedef int ElementType;

#ifndef _QUEUE_
#define _QUEUE_

struct QueueRecord;
typedef QueueRecord *Queue;

int IsEmpty( Queue Q );
int IsFull( Queue Q );
Queue CreateQueue( int MaxElements );
void DisposeQueue( Queue Q );
void MakeEmpty( Queue Q );
void EnQueue( ElementType X, Queue Q );
ElementType Front( Queue Q );
void Dequeue( Queue Q );
ElementType FrontAndDequeue( Queue Q );

#endif
实现文件:queue.cpp

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

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

int IsEmpty( Queue Q )
{
	return Q->Size == 0;
}

int IsFull( Queue Q )
{
	return Q->Size == Q->Capacity;
}

void MakeEmpty( Queue Q )
{
	Q->Size = 0;
	Q->Front = 1;
	Q->Rear = 0;
}

Queue CreateQueue( int MaxElements )
{
	Queue Q;
	Q = (Queue)malloc(sizeof(struct QueueRecord));
	if (Q == NULL)
	{
		printf("Out of space!\n");
		return NULL;
	}
	Q->Array = (ElementType*)malloc(sizeof(ElementType) * MaxElements);
	if (Q->Array == NULL)
	{
		printf("Out of space!\n");
		return NULL;
	}
	Q->Capacity = MaxElements;
	MakeEmpty(Q);
	return Q;
}

void DisposeQueue( Queue Q )
{
	if (Q != NULL)
	{
		free(Q->Array);
		free(Q);
	}
}

static int Succ(int Value, Queue Q)
{
	if (++Value == Q->Capacity)
		Value = 0;
	return Value;
}


void EnQueue( ElementType X, Queue Q )
{
	if (IsFull(Q))
	{
		printf("Queue is full!\n");
		return;
	}
	else
	{
		Q->Size++;
		Q->Rear = Succ(Q->Rear, Q);     //Q->Rear = (Q->Rear + 1) % Q->Capacity ? Q->Rear + 1 : 0;
		Q->Array[Q->Rear] = X;
	}
}

ElementType Front( Queue Q )
{
	if (!IsEmpty(Q))
	{
		return Q->Array[Q->Front];
	}
	printf("Queue is Empty!\n");
	return 0;
}

void Dequeue( Queue Q )
{
	if (!IsEmpty(Q))
	{
		Q->Size--;
		Q->Front = Succ(Q->Front, Q);
	}
	else
	{
		printf("Queue is Empty!\n");
	}
}

ElementType FrontAndDequeue( Queue Q )
{
	ElementType X = 0;
	if (!IsEmpty(Q))
	{
		Q->Size--;
		X = Q->Array[Q->Front];
		Q->Front = Succ(Q->Front, Q);
	}
	else
	{
		printf("Queue is Empty!\n");
	}
	return X;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值