初见 | 数据结构 | 栈 + 队列

这篇Blog就证明我正式进入了万年坑:数据结构

那么这一篇就从最简单的线性表开始

栈 L I F O

L I F O,即 Last In First Out ,体现了栈的特点:这是一个后进先出表

简单来说,栈就像一个井,假设你不断地往里面扔石块(假设石块的大小都和井口大小一样),那么等到井满了,你看到的一定是你最后扔进去的石块。如果你不把井填满,那么你打捞上来的第一块还是你扔下去的最后一块。

栈的基本操作

就如我刚才所举的例子“井”一样,栈是一个底闭合上开口的线性表

那么它大约就长这样:

当然,这张图是栈满的时候的情况,那新的元素怎么再加入呢?

只能先让其中的一个元素出栈在进入新的,否则就溢出了QWQ

根据我刚才举的例子不难看出,先出栈的元素就是栈顶的元素

我们这里将这个操作称为POP()

与这个操作相反的操作,也就是前面所说往里面扔石块的操作,我们称为PUSH()

这样,你就知道了栈的全部操作啦,可以去尝试做题了

不会真有人去吧,代码实现还没放呢

PUSH代码

inline void pusho(int x)
{
	if(top>=n)//n是长度
	cout<<"再PUSH,就溢出了!马鹿!";
	else
	{
		top++;//头指针
		stack[top]=x;
	}
}

POP代码

inline int popo()
{
	if(top<=0)
		cout<<"请问您想从空栈里面拿出来什么东西?是这虚无的气体吗?";
	else
	{
		int x=stack[top];
		top--;
		return x;
	}
}

这样,你就知道了栈的全部操作啦,可以去尝试做题了

不会真有人去吧

众所周知,STL大法好,作为一种基础的线性表,STL必有它

使用之前你需要一个头文件:

#include <stack>

或者是万能头

#include <bits/stdc++.h>

声明一个栈是这样的:

stack<int> s;

这是一种在STL许多容器中极为普遍的声明格式

既然我们有了STL的栈,我们就可以使用它里面带有的函数来执行操作,由于我用不到那么多,这里只说四个

s.push(x);

和上面的push是一样的,即为将元素x压入栈s

s.pop();

和上面的pop是一样的,即为将栈顶元素出栈

s.empty();

这个用来判断栈是否为空,相对来说比较有用

同时,这个.empty()函数也适用于绝大多数的STL容器

s.top();

这个函数是用来取栈顶元素,但是不对这个元素进行操作

也就是说当我们想要知道栈顶是什么的时候,int x=s.top();即可

队列 F I F O

F I F O,就是First In First Out,先进先出表

这种线性表在生活中就非常常见了,我们的排队就是一个简单的队列

队列的基本操作

将我们排队时的队简化一下,就是队列的样子:

这里有两个指针(或者是指针作用的普通变量,我用的时候一般倾向后者)

head,顾名思义,指向队列的头,不过是队列最前面的变量的前面(如图)

tail,顾名思义,指向队列的尾,这里就是直接指向队尾的元素了

那为什么head要提前一个呢?

答:便于判断队列是否已满

和栈一样,队列有两个基本的操作:入队和出队

也就是PUSH和POP

和我们生活中的一样,出队的是在队首的,入队则是从队尾进入,就不在画图

PUSH&POP代码

inline void queueo(int x)
{
	if(x)//这里的x是一个告诉程序要PUSH还是POP的指示性变量,
	//若不为零就PUSH,否则POP
	{
		cin>>t;
		if(tail==n+1)
			tail=1;//这里是为了防止假溢出,于是让队列循环起来,也就是循环队列
		if(head==tail)
			cout<<"这个队列满了就不要往里面塞了(半恼)"
		else
			qi[tail]=t;
	}
	else
		head++;
}

至于这里面提到的循环队列,就是防止假溢出而构造的头尾相接的队列,不知道什么是假溢出的推荐BDFS

同样的,作为一个基础的线性表,STL大法也将其收入麾下

同样的,使用之前你需要一个头文件:

#include <queue>

或者是万能头

#include <bits/stdc++.h>

声明一个队列是这样的,和栈差不多:

queue<int> q;

这里的队列,具体来讲是个无限长度的队列,具体形成和vector类似,当然也可以理解为一个循环队列

同样的,(说了三次了)

既然我们有了STL的队列,我们就可以使用它里面带有的函数来执行操作,由于我用不到那么多,这里只说四个

q.push(x);

和上面的push是一样的,入队x

q.pop();

和上面的pop是一样的,即为将队首元素出队

q.empty();

这个用来判断队列是否为空

q.front();

这个函数是用来取队首元素,但是不对这个元素进行操作,使用方式和STL栈的 .top() 一致

优先队列

有的时候,排队不总是那么的平淡,总是又有点插曲:插队&特权VIP

但是有时候你还不能怎么样他们,比如说他们是一群比你优先级高的人的时候

官大一级压死人,QWQ

这个时候,普通的队列就不能满足我们的需要了,于是乎就出现了优先队列

也就是说,优先级越高的元素越先出队

这里就直接上STL大法:

在和前文一样的头文件声明之后,就可以声明这样一个神圣的队列

priority_queue<int> pq;

然而这还没有完,这里的pq只是一个元素越大越先出队的优先队列,如果我们想要其他的......

STL给我们提供了一些常用的队列:

priority_queue<int,vector<int>,greater<int> > pq;

这就是一个元素越小越先出队的优先队列,至于其他的...

我太菜了不会,可以自行BDFS

至于STL优先队列的函数

前三个都是和队列一样的,第四个有点不同

因为在pq里面先出队的并不一定是先入队的元素,所以我们就不再使用front(),而改为使用pq.top();

End

这差不多就是全部内容了QWQ

我太菜了数据结构完全不会

posted @ 2021-03-24 21:30  HerikoDeltana  阅读(43)  评论(0编辑  收藏  举报