数据结构与算法(队列)

引言:在上次复习栈的基本操作后,这一次我们来复习队列的相关知识与操作。至此——我们开始数据结构队列的学习。

一.队列的定义

在栈的学习中,我们知道栈是一种只能在一端进行操作的数据结构。而队列,是一种可以在两端进行操作的数据结构,是先进先出的操作顺序。
定义:在一端进行插入操作,在另一端进行删除操作。

二.队列的基本操作

1.顺序队列

顺序表达

既然我们知道了队列是两端操作,所以我们定义两个指针用来表达数据。

struct queue//定义队列
{
	int data[Max];//数据域
	int front;//头指针
	int rear;//尾指针
};

同理,以上的是最基本的实现,其他操作要看需求。

顺序插入

void In_queue(struct queue *p,int k)
{
	if(p->rear==Max)
	exit(0);
	p->data[p->rear]=k;
	p->rear++;//让尾指针进行加操作,用于后续数据的插入
}

顺序输出

int Out_queue(struct queue *q)
{
	int e;
	if(q->front==Max)
	exit(0);
	e=q->data[q->front];
	q->front++;//头指针进行操作,让队列达到先进先出的要求
	return e;
}

现在我们来看一下完整代码:

#include <iostream>
using namespace std;
#define Max 103
struct queue
{
	int data[Max];
	int front;
	int rear;
};
void In_queue(struct queue *p,int k)//插入
{
	if(p->rear==Max)
	exit(0);
	p->data[p->rear]=k;
	p->rear++;
}
int Out_queue(struct queue *q)//输出
{
	int e;
	if(q->front==Max)
	exit(0);
	e=q->data[q->front];
	q->front++;
	return e;
}
int main()
{
	int n,m,j,k,l,i;
	struct queue list;
	list.front=0;
	list.rear=0;
	cin>>n;
	for(i=0;i<n;i++)
	{
		cin>>m;
		In_queue(&list,m);
	}
	for(i=0;i<n;i++)
	{
		l=Out_queue(&list);
		cout<<l<<" ";
	}
	return 0;
 } 

2.循环队列

在我们学习的队列的基本使用后,我们来思考,在输出时,front指针时加一的。所以队列在使用后就会有一部分不在重用。所以,我们考虑循环队列
如果我们将数组的首尾相接,那么我们就创立了循环队列。这时,队列长度满足(rear-front+Max)%Max。
我们来看下代码

循环表达

struct queue//和普同的队列是一样,但是其他操作不同
{
	int data[103];
	int front;
	int rear;
};

循环插入

void In_queue(struct queue *p,int k)
{
	if((p->rear+1)%Max==p->front)//判断队列是否满
	exit(0);
	p->data[p->rear]=k;
	p->rear=(p->rear+1)%Max;//指针后移到下一位
}

循环输出

int Out_queue(struct queue *q)
{
	int e;
	if(q->front==q->rear)//判断队列是否为空
	exit(0);
	e=q->data[q->front];
	q->front=(q->front+1)%Max;//指针后移到下一位
	return e;
}

现在我们来看完整代码:

#include <iostream>
using namespace std;
#define Max 103
struct queue
{
	int data[103];
	int front;
	int rear;
};
void In_queue(struct queue *p,int k)//插入
{
	if((p->rear+1)%Max==p->front)
	exit(0);
	p->data[p->rear]=k;
	p->rear=(p->rear+1)%Max;
}
int Out_queue(struct queue *q)//输出
{
	int e;
	if(q->front==q->rear)
	exit(0);
	e=q->data[q->front];
	q->front=(q->front+1)%Max;
	return e;
}
int main()
{
	int n,m,j,k,l,i;
	cin>>n;
	struct queue list;
	list.front=0;
	list.rear=0;
	for(i=0;i<n;i++)
	{
		cin>>m;
		In_queue(&list,m);
	}
	for(j=0;j<n;j++)
	{
		l=Out_queue(&list);
		cout<<l<<" ";
	}
	return 0;
}

3.链式队列

链式队列,其实就是只能在两端操作的单链表
当然,我们这里定义头结点

链式表达

struct queue//队列节点
{
	int data;
	struct queue *next;
};
struct link_Q//队列的链式结构
{
	struct queue *front,*rear;//首尾指针
};

链式初始化

void start_queue(struct link_Q *q)//就是初始化头结点
{
	struct queue *s=new(struct queue);
	s->data=0;
	s->next=NULL;
	q->front=s;
	q->rear=s;
}

链式插入

void In_queue(struct link_Q *p,int k)
{
	struct queue *s=new(struct queue);
	s->data=k;
	s->next=NULL;
	p->rear->next=s;//这里就是链表的尾插法
	p->rear=s;
}

链式输出

int out_queue(struct link_Q *L)
{
	int e;
	struct queue *s;
	if(L->front==L->rear)//判断是否为空
	exit(0);
	s=L->front->next;
	e=s->data;
	L->front->next=s->next;//将原头结点的后续L->next赋值给头结点后续
	if(L->rear==s)
	L->rear=L->front;
	delete(s);
	return e;
}

现在我们可以写出完整代码:

#include <iostream>
using namespace std;
struct queue
{
	int data;
	struct queue *next;
};
struct link_Q
{
	struct queue *front,*rear;
};
void start_queue(struct link_Q *q)//初始化
{
	struct queue *s=new(struct queue);
	s->data=0;
	s->next=NULL;
	q->front=s;
	q->rear=s;
}
void In_queue(struct link_Q *p,int k)//插入
{
	struct queue *s=new(struct queue);
	s->data=k;
	s->next=NULL;
	p->rear->next=s;
	p->rear=s;
}
int out_queue(struct link_Q *L)//输出
{
	int e;
	struct queue *s;
	if(L->front==L->rear)
	exit(0);
	s=L->front->next;
	e=s->data;
	L->front->next=s->next;
	if(L->rear==s)
	L->rear=L->front;
	delete(s);
	return e;
}
int main()
{
	int n,m,j,k,l,i;
	struct link_Q list;
	start_queue(&list);
	cin>>n;
	for(i=0;i<n;i++)
	{
		cin>>m;
		In_queue(&list,m);
	}
	for(i=0;i<n;i++)
	{
		l=out_queue(&list);
		cout<<l<<" ";
	}
	return 0;
}

后记

本次我们写队列的实现,其主要问题就是空间问题,所以我们实现了循环队列。但是动态空间的优势可能更符合我们的需求,所以我们又实现了链式队列。到这里,队列就结束了,我们将继续往下学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风送雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值