数据结构之队列的定义、属性以及算法实现(C/C++描述)

目录

队列定义

顺序的顺序存储

队列的链式存储

循环队列


队列定义

队列是一种受限的线性结构
它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。

顺序的顺序存储

算法实现:采用数组来保存队列的元素,设立一个队首指针 front ,一个队尾指针 rear,分别指向队首和队尾元素。则
rear-front 即为存储的元素个数!

数据结构设计:

#define MaxSize 5 //队列的最大容量

typedef int DataType; //队列中元素类型

typedef struct Queue
{
DataType queue[MaxSize];
int front; //队头指针
int rear; //队尾指
}SeqQueue;
队列初始化
//队列初始化,将队列初始化为空队列
void InitQueue(SeqQueue *SQ)
{
if(!SQ) return ;
SQ->front = SQ->rear = 0; //把对头和队尾指针同时置 0
队列为空
//判断队列为空
int IsEmpty(SeqQueue *SQ)
{
if(!SQ) return 0;
if (SQ->front == SQ->rear)
{
return 1;
}
return 0;
}
队列为满
//判断队列是否为满
int IsFull(SeqQueue *SQ)
{
if(!SQ) return 0;
if (SQ->rear == MaxSize)
{
return 1;
}
return 0;
}
入队 :将新元素插入 rear 所指的位置,然后 rear 加 1。
//入队,将元素 data 插入到队列 SQ 中
int EnterQueue( SeqQueue *SQ,DataType data){
if(!SQ) return 0;
if(IsFull(SQ)){
cout<<"无法插入元素 "<<data<<", 队列已满!"<<endl;
return 0;
}
SQ->queue[SQ->rear] = data; //在队尾插入元素 data
SQ->rear++; //队尾指针后移一位
return 1;
}

队列的链式存储

队列的链式存储结构,其实就是线性表的单链表,只不过它只是尾进头出而已,我们把它简称为链队列。为了
操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端节点
数据结构设计:
typedef struct _QNode
{
    int data;
    struct _QNode *next;

}QNode, *QueuePtr;

typedef struct _Queue
{
    int length;
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
完整操作源码:
//Author:See QQ:3492625357  群号:894356239
//代码为本人手写,若有错误或不当之处欢迎指正。
#include<iostream>
#define MAXSIZE 5
typedef struct _QNode
{
	int data;
	struct _QNode *next;

}QNode, *QueuePtr;

typedef struct _Queue
{
	int length;
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

void InitQueue(LinkQueue *LQ)
{
	if (!LQ) return;
	LQ->length = 0;
	LQ->front = LQ->rear = NULL;
}

bool IsEmpty(LinkQueue *LQ)
{
	if (!LQ) return 0;
	if (LQ->front == NULL)
		return 1;
	return 0;
}

bool IsFull(LinkQueue *LQ)
{
	if (!LQ) return 0;

	if (LQ->length == MAXSIZE)
		return 1;
	return 0;
}

bool EnQueue(LinkQueue *LQ, int e)
{
	if (!LQ || IsFull(LQ))
		return 0;
	QNode *q = new QNode;
	q->data = e;
	q->next = NULL;
	if (IsEmpty(LQ))
	{
		LQ->front = LQ->rear = q;
		return 1;
	}

	LQ->rear->next = q;
	LQ->rear = q;
	LQ->length++;
	return 1;
}

bool DeleteQueue(LinkQueue *LQ, int &e)
{
	if (!LQ || IsEmpty(LQ))
		return 0;

	QNode *tmp = LQ->front;

	e = LQ->front->data;
	LQ->front = LQ->front->next;

	if (LQ->front == NULL) LQ->rear = NULL;
	delete tmp;
	return 1;
}

void PrintQueue(LinkQueue *LQ)
{
	if (!LQ || IsEmpty(LQ)) return;
	QNode *tmp = LQ->front;

	while (tmp)
	{
		std::cout << tmp->data << " ";
		tmp = tmp->next;
	}
	std::cout << std::endl;
}

void ClearQueue(LinkQueue *LQ)
{
	if (!LQ) return;
	while (LQ->front)
	{
		QNode * tmp = LQ->front->next;
		delete LQ->front;
		LQ->front = tmp;
	}
	LQ->front = LQ->rear = NULL;
	LQ->length = 0;

}

int main()
{
	LinkQueue *LQ = new LinkQueue;

	InitQueue(LQ);
	for (int i = 0; i < MAXSIZE; i++)
	{
		EnQueue(LQ, i);
	}
	PrintQueue(LQ);
	return 0;
}

循环队列

在队列的顺序存储中,采用出队方式 2, 删除 front 所指的元素,然后加 1 并返回被删元素。这样可以避免元素
移动,但是也带来了一个新的问题“ 假溢出 ”。
循环队列入队, 队尾循环 后移
SQ->rear =(SQ->rear+1)%Maxsize
循环队列出队, 队首循环 后移 : SQ->front =(SQ->front+1)%Maxsize;
队空 :SQ.front=SQ.rear; // SQ.rear 和 SQ.front 指向同一个位置
队满 : (SQ.rear+1) %Maxsize=SQ.front; // SQ.rear 向后移一位正好是 SQ.front

 

计算元素个数:
可以分两种情况判断:
如果 SQ.rear>= SQ.front:元素个数为 SQ.rear-SQ.front;
如果 SQ.rear<SQ.front:元素个数为 SQ.rear-SQ.front+ Maxsize;
采用取模的方法把两种情况统一为 :(SQ.rear-SQ.front+Maxsize)% Maxsize
完整操作源码:
//Author:See QQ 3492625357  群号:894356239
//代码为本人手写,若有错误或不当之处欢迎指正。
#include<iostream>
#define  MAXSIZE 5
typedef struct _SeQueue
{
	int queue[MAXSIZE];
	int front;
	int rear;
}SeQueue;

void InitQueue(SeQueue *SQ)
{
	if (!SQ) return;
	
	SQ->front = SQ->rear = 0;
}

bool  IsEmpty(SeQueue *SQ)
{
	if (!SQ) return 0;

	if (SQ->front == SQ->rear) return true;
	else return false;
}

bool IsFull(SeQueue *SQ)
{
	if (!SQ) return 0;

	if((SQ->rear + 1)%MAXSIZE == SQ->front)return 1;
	else return 0;
}

bool EnQueue(SeQueue *SQ, int e)
{
	if (!SQ) return 0;
	if (IsFull(SQ)) return 0;

	SQ->queue[SQ->rear] = e;
	SQ->rear = (SQ->rear + 1) % MAXSIZE;
	return 1;
}

bool DeQueue(SeQueue *SQ, int &e)
{
	if (!SQ || IsEmpty(SQ)) return 0;

	e = SQ->queue[SQ->front];
	SQ->front= (SQ->front + 1) % MAXSIZE;
	
	return 1;
}

int getLenth(SeQueue *SQ)
{
	if (!SQ || IsEmpty(SQ)) return 0;

	return (SQ->rear - SQ->front + MAXSIZE) % MAXSIZE;
}

void PrintQueue(SeQueue *SQ)
{

	if (!SQ || IsEmpty(SQ)) return ;

	int i = SQ->front;
	while (i!=SQ->rear)
	{
		std::cout << SQ->queue[i] << " ";
		i = (i + 1) % MAXSIZE;
	}
	std::cout << std::endl;
}
int main()
{
	SeQueue *SQ = new SeQueue;
	InitQueue(SQ);

	for (int i = 0; i < 5; i++)
		EnQueue(SQ, i);

	PrintQueue(SQ);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40582034/article/details/118939861