链队列和循环队列的表示与实现-初始化、判空、求长、入队、出队、遍历、求头、求尾、清队、毁队

        队列:队列是一种先进先出(first in first out,FIFO)的线性表。它只允许在一端进行插入,而在另一端进行删除的元素。在队列中允许插入的元素叫做队尾,允许删除的一端叫做队头。其结构如下:

      

1、链队列-----队列的链式表示与实现

      链队列:用链表表示的队列;

       一个链队列需要两个分别指示队头和队尾的指针(头指针和尾指针)才能唯一确定。

      链队列的存储结构为:

   //链队列的存储结构
typedef struct QNode {
	QElemType data;
	struct QNode *next;
}QNode,*QueuePtr;
typedef struct LinkQueue {
	QueuePtr front;
	QueuePtr rear;
};
     主函数定义:LinkQueue Q;

     判空条件:Q.front=Q.rear;

     判存条件:Q.front=NULL;

     链式队列的初始化、判空、求长、入队、出队、遍历、求头、求尾、清队、毁队代码如下:

#include "stdafx.h"
#include "iostream"
typedef int QElemType;
typedef int Status;
using namespace std;
//链队列的存储结构
typedef struct QNode {
	QElemType data;
	struct QNode *next;
}QNode,*QueuePtr;
typedef struct LinkQueue {  //定义头指针和尾指针
	QueuePtr front;
	QueuePtr rear;
};
//构造一个空队列
Status initQueue(LinkQueue &Q) {
	Q.front = Q.rear = new QNode;
	if (!Q.front)
	{
		exit(OVERFLOW);   //内存分配失败
	}
	Q.front->next = NULL;
	return true;
}
//入队列
Status enQueue(LinkQueue &Q,int e) {
	QueuePtr p;
	p = new QNode;
	p->data = e;
	p->next = NULL;
	Q.rear->next = p;
	Q.rear = p;
	return true;
}
//判队空
Status isEmpty(LinkQueue &Q) {
	if (NULL==Q.front)
	{
		cout << "链队列不存在!" << endl;
		exit(1);
	}
	if (Q.front == Q.rear)
		return true;
	else
		return false;
}
//求队长
Status getLength(LinkQueue &Q) {

	if (isEmpty(Q))
	{
		exit(1);
		return 0;
	}
	else {
		QueuePtr p;
		p = Q.front->next;
		QElemType length = 0;
		while (p)
		{
			length++;
			p = p->next;
		}
		return length;
	}
}
void visit(QElemType e) {
	cout << e << "\t";
}
//遍历队列
Status queueTraverse(LinkQueue &Q) {
	QueuePtr p;
	p = Q.front->next;
	if (isEmpty(Q))
	{
		cout << "队列为空!" << endl;
		return false;
	}
	else
	{
		while (p)
		{
			visit(p->data);
			p = p->next;
		}
		cout << endl;
		return true;
	}
}
//出队
Status deQueue(LinkQueue &Q) {
	if (isEmpty(Q))
	{
		cout << "队伍为空!";
		return false;
	}
	else
	{
		int e;
		QueuePtr p;
		p = Q.front->next;
		Q.front->next = p->next;
		e = p->data;
		if (Q.rear==p)   //此时,若不重新给Q.rear赋值,释放p的同时也将释放Q.rear
		{
			Q.rear = Q.front;
		}
		delete p;
		return e;
	}
}
//求队头
Status getFirstElem(LinkQueue &Q){
	if (isEmpty(Q))
	{
		exit(1);
	}
	return Q.front->next->data;
}
//求对尾
Status getLastElem(LinkQueue &Q) {
	if (isEmpty(Q))
	{
		exit(1);
	}
	return Q.rear->data;
}
//清队
Status clearQueue(LinkQueue &Q) {
	while (!isEmpty(Q))
		deQueue(Q);
	return true;
}
//毁队
Status destroyQueue(LinkQueue &Q) {
	clearQueue(Q);
	delete Q.front;
	Q.front = Q.rear = NULL;
	return true;
}
int main()
{
	LinkQueue queue;
	cout << "初始化队列"<<endl;
	initQueue(queue);
	int i;
	cout << "请输入第一个入队的元素:";
	cin >> i;
	enQueue(queue,i);
	cout << "请输入第二个入队的元素:";
	cin >> i;
	enQueue(queue,i);
	cout << "请输入第三个入队的元素:";
	cin >> i;
	enQueue(queue,i);
	cout << "队伍长度为:";
	cout<<getLength(queue)<<endl;
	cout << "当前队伍为:";
	queueTraverse(queue);
	cout << "执行一次出队操作,出队元素为:" << deQueue(queue) << endl;
	cout << "执行清队操作"<<endl;
	clearQueue(queue);
    return 0;
}

2、循环队列---队列的顺序表示与实现

       2.1:顺序队列


        顺序队列用一组连续的存储单元存放从队列头到队列尾的元素。

      指针front指示队头元素;指针rear指示队尾元素。

      初始化顺序队列的容量为MAXQSIZE;

      当队列为空时:Q.front=Q.rear

      当新插入元素时:Q.rear=(Q.rear+1)%MAXQSIZE;当删除元素时:Q.front=(Q.front+1)%MAXQSIZE;

      满队列:Q.rear-Q.front=MAXSQSIZE;

      若出现下图右侧情况,队列未满,继续插入元素造成数组越界;而此时又不宜像顺序栈那样,再分配来扩大数组空间(队列的实际可用空间未占满),巧妙的解决办法:将队列臆造成一个环状空间,称之为循环队列。

       


       现在又带来了上图右侧的问题,队列为空和队列为满时,都是这个状态:Q.front=Q.rear;


    则循环队列的实现如下:   

#include "stdafx.h"
#include "iostream"
using namespace std;
#define MAXQSIZE 100
typedef int ElemType;
typedef int Status;
typedef struct {
	ElemType *base;   //存储首地址的位置
	int front;
	int rear;
} SqQueue;
//初始化队列
Status initQueue(SqQueue &Q) {
	Q.base = (ElemType *)malloc(MAXQSIZE * sizeof(ElemType));
	if (!Q.base)
		exit(1);
	Q.front = Q.rear = 0;
	return true;
}
//获取队列中元素数量,由于是循环栈,队尾序号可能在队头前面也可能在队头后面
Status getLength(SqQueue &Q) {
	return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}
//插入元素
Status enQueue(SqQueue &Q, ElemType e) {
	//插入元素前应测试队列是否已满
	if ((Q.rear + 1) % MAXQSIZE == Q.front)
		exit(0);
	Q.base[Q.rear] = e;
	Q.rear = (Q.rear + 1) % MAXQSIZE;
	return true;
}
//判空
bool isEmpty(SqQueue &Q) {
	if (Q.base == NULL)
	{
		cout << "队列不存在!" << endl;
		exit(1);
	}
	if (Q.front == Q.rear)  return true;
	else
		return false;
}
//删除元素
Status DeQueue(SqQueue &Q) {
	ElemType e;
	if (isEmpty(Q))
	{
		cout << "队列为空!" << endl;
		exit(0);
	}
	e = Q.base[Q.front];
	Q.front = (Q.front + 1) % MAXQSIZE;
	return e;
}
void visit(ElemType e) {
	cout << e << "\t\t";
}
//遍历循环队列
bool queueTraverse(SqQueue &Q) {
	if (isEmpty(Q))
	{
		cout << "队列为空!" << endl;
		return false;
	}
	int i;
	i = Q.front;
	while (i != Q.rear)
	{
		visit(Q.base[i]);
		++i;
		i = i%MAXQSIZE;
	}
	cout << endl;
	return true;
}
//清队
bool clearQueue(SqQueue &Q) {
	while (!isEmpty(Q))
	{
		DeQueue(Q);
	}
	return true;
}
//毁队
bool destroyQueue(SqQueue &Q) {
	while (!isEmpty(Q))
	{
		DeQueue(Q);
	}
	delete Q.base;
	Q.base = NULL;
	return true;
}
int main()
{
	SqQueue queue;
	cout << "初始化队列" << endl;
	initQueue(queue);
	int elem;
	cout << "第一个进队的元素为:";
	cin >> elem;
	enQueue(queue, elem);
	cout << "第二个进队的元素为:";
	cin >> elem;
	enQueue(queue, elem);
	cout << "第三个进队的元素为:";
	cin >> elem;
	enQueue(queue, elem);
	cout << "此时队列中元素的个数为:" << getLength(queue) << endl;
	cout << "遍历队列:";
	queueTraverse(queue);
	cout << "执行一次出队操作,出队元素为:" << DeQueue(queue) << endl;
	cout << "清除队列" << endl;
	clearQueue(queue);
	queueTraverse(queue);
	cout << "销毁队列" << endl;
	destroyQueue(queue);
	queueTraverse(queue);
	return 0;
}

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值