栈引入栈是 OI 中常用的一种线性数据结构。请注意,本文主要讲的是栈这种数据结构,而非程序运行时的系统栈/栈空间。
栈的修改与访问是按照后进先出的原则进行的,因此栈通常被称为是后进先出(last in first out)表,简称 LIFO 表。
WarningLIFO 表达的是 当前在容器 内最后进来的最先出去。
我们考虑这样一个栈
push(1)
pop(1)
push(2)
pop(2)如果从整体考虑,1 最先入栈,最先出栈,2 最后入栈,最后出栈,这样就成了一个先进先出表,显然是错误的。
所以,在考虑数据结构是 LIFO 还是 FIFO 的时候,应当考虑在当前容器内的情况。
使用数组模拟栈我们可以方便的使用数组来模拟一个栈,如下:
C++1234567891011int st[N];// 这里使用 st[0] (即 *st) 代表栈中元素数量,同时也是栈顶下标// 压栈 :st[++*st] = var1;// 取栈顶 :int u = st[*st];// 弹栈 :注意越界问题, *st == 0 时不能继续弹出if (*st) --*st;// 清空栈*st = 0;
...
C++递归算法学习指南递归是计算机科学中一种非常重要的算法思想。它是指函数直接或间接地调用自身的一种方法。通过递归,我们可以将复杂的问题分解为更小的、与原问题相似的子问题,从而简化问题的求解过程。
一、递归的基本概念递归算法通常包含两部分:基本情况(base case)和递归情况(recursive case)。基本情况是递归的结束条件,当满足这个条件时,函数不再调用自身,而是返回一个值。递归情况是函数调用自身的部分,它通常会将问题分解为更小的子问题。
二、C++递归算法示例下面是一个使用C++编写的递归算法示例,该算法计算一个整数的阶乘:
1234567891011121314151617181920#include <iostream> using namespace std;int factorial(int n) { // 基本情况 if (n == 0 || n == 1) { return 1; } // 递归情况 else { ret ...
队列(queue)本页面介绍和队列有关的数据结构及其应用。
引入队列本着“先进后出”(FIFO)的原则,是一种具有「先进入队列的元素一定先出队列」性质的表。由于该性质,队列通常也被称为先进先出(first in first out)表,简称 FIFO 表。下面是队列的示意图:
数组模拟队列通常用一个数组模拟一个队列,用两个变量标记队列的首尾。1int q[SIZE], ql = 1, qr;
插入元素:q[++qr] = x;
删除元素:ql++;
访问队首:q[ql]
访问队尾:q[qr]
清空队列:ql = 1; qr = 0;
双栈模拟队列还有一种方法是使用两个 栈 来模拟一个队列。
这种方法使用两个栈 F, S 模拟一个队列,其中 F 是队尾的栈,S 代表队首的栈,支持 push(在队尾插入),pop(在队首弹出)操作:
push:插入到栈 F 中。
pop:如果 S 非空,让 S 弹栈;否则把 F 的元素倒过来压到 S 中(其实就是一个一个弹出插入,做完后是首尾颠倒的),然后再让 S 弹栈。容易证明,每个元素只会进入/转移/弹出一次,均摊复杂度 O(1)。
C++ S ...
数据排序[例] 统计字符数[题目] 给定一个由a~z这26个字符组成的字符串,统计其中哪个符号出现的次数最多。
[输入] 输入包括一行,一个字符串,一个整数,长度不超过1000。
[输出] 输出一行,包括出现次数最多的字符和该字符出现的次数,中间用一个空格分开。如果有多个字符出现的次数相同且最多,那么输出ASCII码最小的那一个字符。
[样例输入]1abbcc
[样例输出]1c 3
[例题参考答案]123456789101112131415161718192021。#include <iostream>#include <cstdio>#include <cstring>using namespace std;int maxn, a[26];string s;char ans;int main() { cin >> s; for(int i = 0; i < s.size(); i++) { a[s[i] - 'a']++; //将s的第 ...
C++七大经典排序算法详解前言:排序是将一组数据,按照指定的顺序或要求来进行排列的过程。是数据结构相关课程和内容较为重要和核心的内容之一,常常作为考试题和面试题目来考察学生和面试者,因此熟练掌握经典的排序算法原理和代码实现是非常重要的本文介绍了几大较为经典的排序算法:插入、希尔、选择、堆、冒泡、快速和归并排序
各种排序算法动图解析请参考
各种排序算法复杂度对比冒泡排序:两两比较,将大的元素不断后移;选择排序:在一次遍历中,选择最小的元素,和从起始位置开始的元素交换;插入排序:选择一个元素,若此元素比前一个元素大,while循环不断左移找到它的位置。希尔排序:在插入排序的基础之上加入了一个gap步长进行排序归并排序:数组分治,将有序的子数组合并快速排序:在数组中选择一个基准找到它的位置,接着从基准的两边采用同样的方法分治。堆排序:先对整个数组构建大顶堆,接着从根节点开始不断调整。
冒泡排序法冒泡排序是所有排序算法中相对简单且容易理解的算法,它的核心思想:通过for循环不断遍历需要排序的元素,依次比较相邻的两个元素,若不满足指定的顺序(可以从大到小排序,也可以反过来),就交换两个元素,直 ...
1.桶排序本页面将简要介绍桶排序。
定义桶排序(英文:Bucket sort)是排序算法的一种,适用于待排序数据值域较大但分布比较均匀的情况。
过程桶排序按下列步骤进行:
设置一个定量的数组当作空桶;
遍历序列,并将元素一个个放到对应的桶中;
对每个不是空的桶进行排序;
从不是空的桶里把元素再放回原来的序列中。
性质稳定性如果使用稳定的内层排序,并且将元素插入桶中时不改变元素间的相对顺序,那么桶排序就是一种稳定的排序算法。
由于每块元素不多,一般使用插入排序。此时桶排序是一种稳定的排序算法。
时间复杂度桶排序的平均时间复杂度为 O(n + n^2/k + k)(将值域平均分成 n块 + 排序 + 重新合并元素),当 k\approx n 时为 O(n)。
桶排序的最坏时间复杂度为 O(n^2)。
实现1234567891011121314151617181920212223242526272829303132const int N = 100010;int n, w, a[N];vector<int> bucket[N];void insertion_sort(vect ...
[引入] 信息获取后通常需要进行处理,处理后的信息其目的便于人们的应用。信息处理方法有多种,通常有数据的排序、查找、插入、删除、归并等操作。
[STD库的排序方法] STD库中存在一个排序函数,叫sort,这个函数在库algorithm(通过代码#include<algorithm>导入)
sort函数的使用方法
1sort(头指针,尾指针);
举例:将a数组的下表为1~n项排序
1sort(a+1,a+n+1);//下表从0开始
[选择排序]<基本思想> 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在待排序的数列的最前面,直到全部待排序的数据元素都排序完。
<代码实现>1234567891011121314151617int a[20005];void psort(int l, int r) { //此函数的意义:排序a数组的l~r的位置的元素 for(int i = l; i < r; i++) { //j=i+1,当i=r时j(i+1)>r ...