栈与队列note

1.栈的特性

在这里插入图片描述
在这里插入图片描述
需要两个指针,base指向栈底,top指向栈顶。

2.顺序栈的动态分配

在这里插入图片描述

3.顺序栈的静态分配

在这里插入图片描述

4.栈(stack)的基本操作(STL)

在这里插入图片描述

5.队列的特性

在这里插入图片描述
在这里插入图片描述

6.顺序队列的动态分配

在这里插入图片描述

7.顺序队列的静态分配

在这里插入图片描述

8.循环队列的队满

在这里插入图片描述
在这里插入图片描述

9.循环队列的入队

在这里插入图片描述
在这里插入图片描述

10.循环队列的出队

在这里插入图片描述
在这里插入图片描述

11.循环队列的队列长度

在这里插入图片描述
在这里插入图片描述

12.队列(queue)的基本操作(STL)

在这里插入图片描述

13.双端队列(deque)的基本操作(STL)

双端队列同时具有队列和栈的特性,如若从队头入队出队,则类似于队列,如若从队尾入队出队,则类似于队尾。

在这里插入图片描述

练习

01 栈

题目:https://www.luogu.com.cn/problem/P1739
题解:根据题意,只有左右小括号,可以将左括号入栈,遇到右括号时,弹出栈顶的左括号。如果表达式处理完毕后,栈中还有元素即不为空,说明左括号多了则输出NO,如果为空的话说明括号全部匹配则输出YES。若先遇到了右括号,则直接输出NO,不用管后面的表达式了。

#include <stack>
#include <iostream>
using namespace std;

int main(void)
{
    
    
	char input_string; 
	stack<char> str; //声明char类型的栈
	while(cin >> input_string && input_string!='@')
	{
    
    
		if (input_string == '(')
		{
    
    
			str.push(input_string);
		}
		if (input_string == ')')
		{
    
    
			if (str.empty())
			{
    
    
				cout << "NO" << endl;
				return 0; //如果第一个遇到 )则直接输出NO且结束
			}
			else {
    
    
				str.pop();
			}
		}
	}
	if (str.empty()) 
	{
    
    
		cout << "YES" << endl;
	}
	else {
    
    
		cout << "NO" << endl;
	}	
}

02 栈

题目:https://www.luogu.com.cn/problem/UVA442
题解:
在这里插入图片描述
首先将矩阵及行列值存储在数组中,然后读入一行矩阵表达式(表达式是合法的,不用担心括号匹配等合法性),遇到矩阵名称入栈,遇到右括号则出栈两个矩阵m2,m1,如果m1的列不等于m2的行,则矩阵不可乘,否则计算乘法次数,并将两个矩阵相乘后的结果矩阵入栈。

#include <iostream>
#include <stack>
using namespace std;

//因为要存取矩阵的名称char类型和矩阵的大小int类型,在Python中用字典存储,在C++中用结构体存储
//定义结构体时,关于矩阵的名称是A,B,C这些,可以减去'A'后转化成整数,其值表示26个结构体中的索引
struct Matrix {
    
    
	//char name; //矩阵名称
	int row; //行
	int col; //列
	//这里使用构造函数,方便整体赋值
	//若不加下面这段构造函数:赋值需要单独赋值 max_matrix[1].row=5,max_matrix[1].col=3
	//加了构造函数之后,可以整体赋值  Matrix(5,3)
	Matrix(int row=0,int col=0):row(row),col(col){
    
    } 
};

int main(void)
{
    
    
	int num_matrix; //输入矩阵的个数
	cin >> num_matrix;

	Matrix max_matrix[26]; //定义最大的矩阵个数
	char matrix_name;

	//对于矩阵名字符串的处理
	for (int i = 0; i < num_matrix; i++)
	{
    
    
		cin >> matrix_name;
		int matrix_index = matrix_name - 'A'; //转换成整数
		cin >> max_matrix[matrix_index].row >> max_matrix[matrix_index].col; //输入矩阵的行和列
	}

	string str;
	stack<Matrix> s; 
	while (cin >> str)
	{
    
    
		int num_mul = 0;//乘法次数
		bool flag = false;
		
		for (int i = 0; i < str.size(); i++)
		{
    
    
			//或者使用 if (isalpha(str[i]))  // isalpha():判断是否是字母
			if (str[i] >= 65 && str[i] <= 90) // 如果输入的矩阵名在A到Z之间,则入栈s
			{
    
    
				s.push(max_matrix[str[i] - 'A']); 
			}
			else if (str[i] == ')')
			{
    
    
				Matrix m2 = s.top();
				s.pop();
				Matrix m1 = s.top();
				s.pop();
				if (m1.col != m2.row) //判断m1的列是否和m2的行相等
				{
    
    
					flag = true;
					break;
				}
				num_mul += m1.row * m1.col * m2.col;
				//如果结构体Matrix中没写构造函数的话,需要如下:
				/*Matrix tmp;
				tmp.row = m1.row;
				tmp.col = m2.col;
				s.push(tmp);*/
				s.push(Matrix(m1.row, m2.col));
			}
		}
		if (flag)
			cout << "error" << endl;
		else
			cout << num_mul << endl;
		
	}
	return 0;
}

03 队列

题目:https://www.luogu.com.cn/problem/UVA12100
题解:
本题中输入是:T组数据,每组数据中输入数据的个数、关心的任务在队列中的位置。(这里输入的数据是打印任务的优先级,范围是1~9)
每次都是从数据的头部取出一个任务J,若J的优先级不低于整组数据中的最高优先级,则直接打印任务J,即J从该组数据中删除,否则若小于整组数据中的最高优先级,则放到整组数据的尾部。(头部出,尾部进,满足队列的特性)
这里取出任务J后,要如何知道整组数据中的最高优先级?如果每取一个任务,都与剩下的任务进行比较,则时间复杂度为O(n²),显然不合理;若一开始就把整组数据进行降序排好,则以后每次比较时,先取降序数据中的第一个元素,若没这个大,则J出队列pop(),再push()到队尾,若不低于这个,则直接打印任务J,降序后的数据组中索引往后移一位。
为了数据降序的方便,使用STL中的vector,如下

 sort(b.begin(), b.end(), greater<int>()); //将数据中的打印任务按优先级降序
3            //输入3组数据
1 0          //有1个数据,关注的任务位置是0
5            //第1组数据:5
4 2          //有4个数据,关注的任务位置是2
1 2 3 4      //第2组数据:1 2 3 4
6 0          //有6个数据,关注的任务位置是0
1 1 9 1 1 1  //第2组数据:1 1 9 1 1 1
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main(void)
{
    
    
	int T_class_data; //定义数据的组数
	cin >> T_class_data;

	for (int i = 0; i < T_class_data; i++)
	{
    
    
		int num_data, care_index_data; //定义每组数据中的数据个数、关注的任务在队列中的位置
		cin >> num_data >> care_index_data;

		vector<int> a_orig_data; //存储每个任务的优先级,即输入的数据
		vector<int> b_sorted_data; //按优先级降序后的数据
		queue<int> q_orig_index_data; //队列用以存储每个打印任务的索引

		for (int i = 0; i < num_data; i++)
		{
    
    
			int data;
			cin >> data;
			a_orig_data.push_back(data);
			b_sorted_data.push_back(data);
			q_orig_index_data.push(i);
		}

		//将每组数据中的元素优先级进行降序。从该容器中第一个元素开始,是优先级最高的,每打印一次,往后加一个,则保证是最大的
		sort(b_sorted_data.begin(), b_sorted_data.end(), greater<int>()); //将数据中的打印任务按优先级降序

		int max_index = 0; //在已降序后的b_sorted_data中的索引
		int print_order = 0;
		while (!q_orig_index_data.empty())
		{
    
    
			int temp = q_orig_index_data.front();
			if (a_orig_data[temp] < b_sorted_data[max_index])
			{
    
    
				q_orig_index_data.pop(); //弹出队首
				q_orig_index_data.push(temp); //从队尾入队
			}
			else
			{
    
    
				//如果队首下标刚好等于关注的任务下标,则直接打印 ++k,因为k是索引从0开始,而输出的第几个打印的从1开始
				if (temp == care_index_data)
				{
    
    
					cout << ++print_order << endl;
					break;
				}
				else
				{
    
    
					q_orig_index_data.pop();
					print_order++;
					max_index++;
				}
			}
		}
	}
}

Guess you like

Origin blog.csdn.net/qq_45445740/article/details/112197119