
算法和数据结构
文章平均质量分 76
尽可能把一切有用的算法收集汇总整理
源代码•宸
我们终此一生,就是要摆脱他人的期待,找到真正的自己
展开
-
高级算法设计——网络流问题
网络流问题HDU3549EK算法求解最大流HDU1532法一、EK算法求解法二、Dinic算法求解原创 2022-10-18 15:48:25 · 510 阅读 · 0 评论 -
图的存储——链式前向星
C++代码如下:样例运行结果如下:原创 2022-10-18 10:31:32 · 429 阅读 · 0 评论 -
计算两个任何长度的整数之和(自定义函数通过数组装超大整数)
我们知道C语言int所能表示的数字范围是-2~ 2-1,所能表示的最大整数为2147483647,那么long long所能表示的数字范围是-2~ 2-1,所能表示的最大整数为9223372036854775807,那么如果我们想计算更大的数据呢,那C的基本数据类型就做不到了,所以这里我们需要数组。...原创 2022-08-16 14:13:19 · 457 阅读 · 0 评论 -
题库敲敲打打
1灵活法(全排列)#include<bits/stdc++.h>using namespace std;int book[4] = {0};int a[4] = {1, 2, 3, 4};int b[3] = {0};int n = 3;int cnt = 0; void dfs(int step){ if(step == n) { for(int i = 0; i < 3; i++) { cout << b[i] <<原创 2021-12-25 21:08:03 · 875 阅读 · 0 评论 -
数据结构与算法之查找算法——哈希表(又称散列表)
哈希表也称为散列表,也是用来查找指定元素的一种方法。散列表是根据关键字直接进行访问的数据结构。散列表通过散列函数将关键字映射到存储地址,建立了关键字和存储地址之间的一种直接映射关系。这里的存储地址可以是数组下标、索引、内存地址等。利用哈希表查找元素需要解决两个问题:构造哈希表和处理冲突。在图8-75中,如果要查找48,就可以通过散列函数得到其存储地址,直接找到该关键字。散列表查找的时间复杂度与表中的元素个数无关。理想情况下,散列表查找的时间复杂度为O(1)。但是,散列函数可能会把两个或两个以上的关原创 2021-11-02 20:49:32 · 1546 阅读 · 0 评论 -
数据结构与算法之图(C++)
图的基本术语图通常用一个二元组G=<V, E>表示,V表示顶点集,E表示边集。|V|表示顶点集中元素的个数,即顶点数,n个顶点的图称为n阶图。|E|表示边集中元素的个数,即边数。注意:顶点集V和边集E均为有限集合,其中E可以为空集,V不可以为空集,但在运算中,可能产生V为空集。V为空集的图称为空图,记为φ。1.无向图若图G中每条边都是没有方向的,则称为无向图。每条边都是两个顶点组成的无序对,例如顶点v1和顶点v3之间的边,记为(v1, v3)或(v3, v1),2.有向图若图G中每原创 2021-10-31 11:20:23 · 1007 阅读 · 0 评论 -
数据结构与算法之排序(C/C++代码)
交换排序交换的意思是根据两个关键字值的比较结果,不满足次序要求时交换位置。冒泡排序和快速排序是典型的交换排序算法,其中快速排序是目前最快的排序算法。冒泡排序冒泡排序是一种最简单的交换排序算法,通过两两比较关键字,如果逆序就交换,使关键字大的记录像泡泡一样冒出来放在尾部。重复执行若干次冒泡排序,最终得到有序序列。算法图解经过第一趟排序后,最大的记录已经冒泡到最后一个位置,第二趟排序不需要再参加。少说废话上代码#include<stdio.h>void swap(int *a原创 2021-10-31 10:57:09 · 1601 阅读 · 0 评论 -
数据结构与算法之树、二叉树(C++)以及关于建树为何用二级指针超详细不劝退教程
树形结构是一对多的非线性关系。无论是顺序存储,还是链式存储,线性表均有其优缺点。顺序存储可以在O(1)时间内找到特定次序的元素,但是插入和删除元素需要移动大量元素,需要O(n)时间;而链式存储插入和删除元素需要O(1)时间,找到特定次序的元素需要从链表头部向后查找,需要O(n)时间。树形结构结合了两者的优点,可以在O(logn)的时间内完成查找、更新、插入、删除等操作。在实际应用中,很多算法可以借助于树形结构高效地实现。树形结构就像一棵倒立的树,有唯一的树根,树根可以发出多个分支,每个分支也可以继续发出分原创 2021-10-02 21:12:32 · 1801 阅读 · 1 评论 -
数据结构与算法之栈和队列基础——顺序队列、循环队列、链队列(C++)以及栈和队列的应用附解密QQ号
先进先出FIFO这种先进先出(First In First Out, FIFO)的线性序列,称为“队列”。队列也是一种线性表,只不过它是操作受限的线性表,只能在两端操作:一端进,一端出。进的一端称为队尾(rear),出的一端称为队头(front)。队列可以用顺序存储,也可以用链式存储。顺序队列的定义队列的顺序存储采用一段连续的空间存储数据元素,并用两个整型变量记录队头和队尾元素的下标。顺序队列的结构体定义(动态分配)顺序队列的结构体定义(静态分配)注意:队列只能在一端进、一端出,不允许在原创 2021-09-10 20:50:09 · 608 阅读 · 0 评论 -
数据结构与算法之栈和队列基础——顺序栈与链栈(C与C++双人打)
栈后进先出(Last In First Out, LIFO)的线性序列,称为“栈”。栈也是一种线性表,只不过它是操作受限的线性表,只能在一端进出操作。进出的一端称为栈顶(top),另一端称为栈底(base)。栈可以用顺序存储,也可以用链式存储,分别称为顺序栈和链栈。顺序栈顺序栈的存储方式顺序栈需要两个指针,base指向栈底,top指向栈顶。顺序栈的结构体定义(动态分配的形式)栈定义好了之后,还要先定义一个最大的分配空间,顺序结构都是如此,需要预先分配空间,因此可以采用宏定义。上面的结构原创 2021-09-10 20:48:53 · 547 阅读 · 0 评论 -
获取素数——埃氏筛法(NB!)附PAT 1013、问题 B: Prime Number
素数的判断bool isPrime(int n){ if(n<=1) return false; for(int i=2;i*i<=n;i++) { if(n%i==0) return false; } return true;}埃氏筛法#include<bits/stdc++.h>using namespace std;const int maxn = 101;//p数组存放素数i对应的bool值 bool p[maxn] = {0};//p原创 2021-06-03 19:50:19 · 161 阅读 · 0 评论 -
数据结构与算法之线性表基础——双向链表、循环链表以及线性表的应用(C与C++双人打)
双向链表的存储方式单链表只能向后操作,不可以向前操作。为了向前、向后操作方便,可以给每个元素附加两个指针域,一个存储前一个元素的地址,另一个存储下一个元素的地址。这种链表称为双向链表双向链表每个节点包含3个域:数据域和两个指针域。两个指针域分别存储前后两个元素节点的地址,即前驱和后继,因此指针指向的类型也是节点类型。双向链表的基本操作下面以带头节点的双向链表为例,讲解双向链表的初始化、创建、取值、查找、插入、删除操作。初始化双向链表初始化是指构建一个空表。先创建一个头节点,不存储数据,然后原创 2021-06-01 15:53:18 · 243 阅读 · 0 评论 -
2019年哈尔滨工程大学211算法设计链表题
链表题目C++解法(考场上代码可以不用这么细致,这里有些提示文字是为了方便调试)#include<bits/stdc++.h>using namespace std;typedef int ElemType;typedef struct LNode{ ElemType data; struct LNode *next;}LNode, *LinkList;void CreateList_R(LinkList &L){ int n; LinkList s, r原创 2021-05-31 20:55:47 · 182 阅读 · 0 评论 -
数据结构与算法之时间复杂度、数据结构的概述、线性表题库
第一章 绪论 时间复杂度、数据结构的概述1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。在有些情况下,数据元素也称为元素、结点、记录等。数据元素用于完整地描述一个对象,如一个学生原创 2021-05-31 18:34:04 · 851 阅读 · 0 评论 -
数据结构与算法之线性表基础——单链表(C与C++双人打)
单链表链表是线性表的链式存储方式。逻辑上相邻的数据在计算机内的存储位置不一定相邻单链表的存储方式可以给每个元素附加一个指针域,指向下一个元素的存储位置每个节点包含两个域:数据域和指针域。数据域存储数据元素,指针域存储下一个节点的地址,因此指针指向的类型也是节点类型。每个指针都指向下一个节点,都是朝一个方向的,这样的链表称为单向链表或单链表。单链表的节点结构体定义定义了节点结构体之后,就可以把若干个节点连接在一起,形成一个单链表不管这个铁链有多长,只要找到它的头,就可以拉起整个铁链。因此,原创 2021-05-31 19:47:39 · 1028 阅读 · 0 评论 -
数据结构与算法之线性表基础——顺序表(C与C++双人打)
人狠话不多,干货先上咯先来个简单的线性表基本构造代码以及响应的运行测试程序seq.h#include<stdio.h>#include<string.h>#define MAXSIZE 100 //定义线性表的最大长度typedef struct{ char key[15]; //结点的关键字 char name[20]; int age;}DATA; //定义结点类型,可定义为简单类型,也可定义为结构typedef struct原创 2020-10-19 15:00:28 · 491 阅读 · 0 评论 -
水题找自信——问题 A: 简单计算器(栈的应用)
每日刷题(110)问题 A: 简单计算器题目描述读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。输入测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。输出对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。样例输入30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 *原创 2021-04-18 08:11:52 · 232 阅读 · 0 评论 -
求解最小公倍数方法(附加更易懂的欧几里得算法(辗转相除法)及其定理证明)1818 最大公约数和1984 最大公约数 2135 最小公倍数 问题 A: Least Common Multiple
1818 最大公约数题目描述输入两个正整数,求其最大公约数。欧几里得算法基于下面定理0和任意一个整数a的最大公约数都是a因此我们可以得到1、递归式:gcd(a, b) = gcd(b, a % b)2、递归边界:gcd(a, 0) = a1984 最大公约数题目描述2135: 最小公倍数题目描述问题 A: Least Common Multiple题目描述最小公倍数相关知识要素最小公倍数求解是建立在最大公约数d基础上,a和b的最小公倍数 = a * b / d求多个最小公倍数方法原创 2020-12-05 10:02:40 · 418 阅读 · 2 评论 -
数学之美——一波骚操作搞定交换变量
一般在大家印象里交换变量值就是用t或者temp,a倒入t,t暂存a值,a再装b(逼),然后b装a这样的套路这里要介绍一个失传已久但是大多数人都见过但是平常不怎么用的方法#include<stdio.h>int main(){ int a, b; scanf("%d%d", &a, &b); a = a + b; b = a - b; a = a - b; printf("%d %d\n", a, b); return 0;}之后我会持续更新,如果喜原创 2020-09-04 17:45:16 · 556 阅读 · 0 评论 -
以后写程序再也不用记π的数值啦(一行代码就搞定)
以前定义π一直都是输3.14159,现在终于可以输得精确点了而且还不用记关键代码:const double pi = acos(-1.0);#include<stdio.h>#include<math.h>int main(){ const double pi = acos(-1.0); double r, h, s1, s2, s; scanf("%lf%lf", &r, &h); s1 = pi * r * r; s2 = 2 * pi *原创 2020-09-04 16:12:34 · 321 阅读 · 0 评论 -
欧几里得算法(The-Euclidean-algorithm)一行代码搞定gcd(int a, int b)
趣味入门故事为何要在余下的土地里找最大方块?为何适用于这小块地的最大方块,也是适用于整块地的最大方块呢?这就涉及到今天的主角——欧几里德算法欧几里得算法(The-Euclidean-algorithm)这些项的顺序不重要,因此:GCD(A,B)=GCD(B,R)相关数学知识之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!...原创 2020-10-24 21:47:42 · 497 阅读 · 0 评论 -
算法小模型(猜数字与掷骰子)
函数srand用来初始化随机数发生器,然后使用rand()函数来生成随机数。要使用这两个函数,需在源程序头部包含“time.h”头文件注:在用rand函数模拟现实生成随机数之前,要先执行srand随机数发生器的初始化函数1、猜数字#include<stdio.h>#include<time.h>int main(){ int n, m, i = 0; srand(time(NULL)); //初始化随机数发生器 n = rand() % 100 + 1; //生原创 2020-09-11 16:52:49 · 568 阅读 · 0 评论 -
算法一:递归(包含Hanoi问题、N皇后问题、逆波兰表达式、爬楼梯、放苹果、全排列)
递归递归在算法中具有很重要的地位,也是很多学习编程的初学者非常头疼的问题,看我的这篇文章,希望能为还处于迷雾中的你带来希望首先我们要知道递归的作用:1.可替代多重循环2.解决本来就是用递归形式定义的问题3.将问题分解为规模更小的子问题进行求解其实对于我来说,递归非常重要的原因在于可以替代多重循环,当循环过大时,会给计算机相当大的负荷,一时半会很难出结果,这时候我们就需要运用到递归这个手...原创 2020-03-12 15:28:35 · 558 阅读 · 0 评论 -
算法一:递归(二)(递归求阶乘、数制转换、计数、求和、求最大值)附如何书写企业级规范C格式
所谓递归算法,就是在程序中不断反复调用自身来求解问题的方法。这里强调的重点是调用自身,就得等待求解的问题能够分解为相同问题的一个子问题,这样通过多次递归调用,自己便可完成求解。递归算法的具体实现过程一般通过函数(或子过程)来完成,在函数(或子过程)的内部,编写代码直接或者间接地调用函数(或子过程)自己,即可完成递归操作。这种函数也称为“递归函数”。在递归函数中,主调函数同时又是被调函数。执行递归函数将反复调用其自身,每调用一次就进入新的一层。从递归算法的实质可以看出,递归算法也是一种循环,只是这种循环不原创 2020-09-10 10:09:33 · 401 阅读 · 0 评论 -
算法二:暴力枚举(优化版)(内含称硬币、种草、熄灯问题等典型例题)
例题一、完美立方可以得出一些关键信息,a,b,c,d > 1, b <= c <= d, b < n,c < n, d < n;详细C代码如下:#include<stdio.h>int main(){ int a, b, c, d; int n; scanf("%d", &n); for(a = 2; a <= ...原创 2020-03-16 23:12:20 · 3135 阅读 · 1 评论 -
算法二:枚举(穷举)(二)
引子:#include<stdio.h>int main(){ int oldprice, price = 0, i = 0; printf("首先设置商品真实价格:"); scanf("%d", &oldprice); system("cls"); printf("请输入试猜价格:\n"); while(oldprice != price){ i++; printf("参与者:"); scanf("%d", &price); printf("原创 2020-09-08 19:13:37 · 191 阅读 · 0 评论 -
算法三:二分查找(与快排相结合)
程序或算法的时间复杂度我们为何要考虑二分查找呢,那是因为在面对很大的数据时它能有效的减少程序运行耗费的时间1.1、标准二分法查找代码二分查找的前提是给定目标数据应该是单调的,要么按从小到大顺序排,要么按从大到小排,也就是说给定的数组事先要排好序函数BinarySearch用于查找某个设定的元素,前提是在从小到大排序的数组里查找,size表示数组的里元素的数目,找到则返回元素下标,否则返回...原创 2020-03-16 08:42:56 · 380 阅读 · 0 评论 -
算法四:分治(归并排序和快速排序经典代码)
分治思想概念其中会涉及到递归和二分思想,废话不多说,直接上干货例题一、归并排序之前也提到了,归并就是把一个大数据分成两组,分别对两组排序然后不断细分直到只剩1个元素时,然后把每每对半分的数据组合并形成有序数组#include<stdio.h>void Merge(int a[], int s, int m, int e, int tmp[]){ int pb = 0...原创 2020-03-19 11:26:25 · 571 阅读 · 0 评论 -
算法四:分治(二)
分治算法的思路是:对于一个规模为N的问题,若该问题可以容易地解决(比如说规模N较小),则直接解决,否则将其分解为M个规模较小的子问题,这些子问题互相独立,并且与原问题形式相同,递归地解决这些小的子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。一般具有以下特征的问题可使用分治法来求解:求解问题可以分解为若干个规模较小的相同问题;求解问题的规模分解到一定的程度后,就能够很容易地求解;合并子问题的解可以得到求解问题的解;由求解问题所分解出的各个子问题是相互独立的使用分治法原创 2020-09-10 19:32:26 · 240 阅读 · 0 评论 -
算法五:动态规划(数字三角形、最长上升子序列、最长公共子序列、神奇的口袋、斐波那契数列记忆化搜索、数塔、最大连续子序列和、最长不下降子序列(LIS))
例题一、数字三角形递归代码如下:#include<stdio.h>#define MAX 101int max(int a, int b){ return a > b ? a : b;}int D[MAX][MAX];int n;int MaxSum(int i, int j){ if(i == n) return D[i][j]; i...原创 2020-03-29 20:59:45 · 341 阅读 · 0 评论 -
算法六:递推(编程老师肯定没告诉过你简单的斐波那契数列也可以和黄金分割比联系起来)
递推算法是一种很常用的算法思想,在数学计算等场合有着广泛的应用。该算法适用于有明确公式的情况,通过已知条件,利用特定关系得出中间推论,逐步递推,直至得到结果为止。不断利用已有的信息推导出新的东西。利用现有信息得到新信息,是递推算法的核心。递推算法可分为顺推法和逆推法两种1、顺推法从已知条件出发,逐步推算出要解决问题的方法。例如,斐波那契数列就可以通过顺推法不断递推算出新的数据。2、逆推法从已知的结果出发,用迭代表达式逐步推算出问题开始的条件,即顺推法的逆过程。例题一、顺推实例:斐波那契数列原创 2020-09-09 19:58:52 · 1018 阅读 · 0 评论 -
算法七:贪婪算法
贪婪算法总是做出在当前看来最好的选择。也就是说,贪婪算法并不从整体最优考虑,它所做出的选择只是局部最优选择。虽然贪婪算法不能对所有问题都得到整体最优解,但对大部分问题它还是能产生整体最优解的。在一些情况下,即使贪婪算法不能得到整体最优解,其最终结果却是最优解的近似解。贪婪算法常以当前情况为基础做最优选择,而不考虑各种可能的整体情况,所以贪婪算法不要回溯。贪婪算法就是通过做局部最优(贪婪)选择来达到全局最优解。使用贪婪算法时,通常采用自顶向下的方法来求解,每一步都使用最贪婪的选择,使原问题变为一个相似的、规原创 2020-09-11 09:47:02 · 637 阅读 · 0 评论 -
算法八:试探(回溯)
试探法也称为回溯法,它是一种系统地搜索问题解的方法,该算法设计思想适用范围相当广泛。试探法是搜索算法中的一种控制策略。它的基本思想是:从问题的某一种状态(一般是默认的初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候,先退几步,接着从另一种可能的“状态”出发,继续搜索,直到所有的“路径”都尝试过。对于常见的迷宫问题,就可使用试探法来求解,具体过程为:进入迷宫后,先随意选择一个前进方向,一步步向前试探前进,如果碰到死胡同,说明前进方向已无路可走,这时,首先看其他方向是否还有原创 2020-09-11 16:01:00 · 1256 阅读 · 0 评论 -
算法九:基本数据结构与算法——选择排序(Selection Sort)
选择排序(Selection Sort)的基本思想:对n个记录进行扫描,选择最小的记录,将其输出,接着在剩下的n-1个记录中扫描,选择最小的记录将其输出……不断重复这个过程,直到只剩一个记录为止,即可完成数据从小到大的排序过程。简单选择排序法类似人的排序习惯:(1)首先从原始数组中选择最小的一个数据,将其和位于第1个位置的数据交换位置。(2)再从剩下的n-1个数据中再选择最小的一个数据,将其和位于第2个位置的数据交换位置。(3)不断重复上述过程,直到最后两个数据完成交换。最后,便完成了对原始数组从原创 2020-09-27 21:06:39 · 291 阅读 · 0 评论 -
算法九:排序概论&快速排序法Quick Sort(C/C++)以及生成随机数的小示例
排序是将一组数据按递增或递减的顺序排列。排序算法是一种基本的、常用的算法。虽然排序看似简单,但在实际应用中往往面临一些问题。因为实际应用中的数据量是很大的,所以要根据合适的问题寻找一个高效的排序算法。排序算法分类1.内部排序若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。内部排序又分为多种方法,可分为4类:插入排序、选择排序、交换排序和合并排序2.外部排序使用内部排序时,所有待处理的数据都已调入到计算机内存中,在排序操作时可直原创 2020-09-20 15:24:08 · 592 阅读 · 0 评论 -
算法九:进行了优化的冒泡排序法Bubble Sort(绝大多数老师绝对没讲过的冒泡优化)
冒泡排序法的基本思想如下:(1)对数组中的各数据,依次比较相邻的两个元素的大小。(2)如果前面的数据大于后面的数据,就交换这两个数据。经过第一轮的多次比较排序后,便可把最小的数据排好。(3)用同样的方法把剩下的数据逐个进行比较,最后便可按照从小到大的顺序排好数组中各数据的顺序。此排序法就像气泡在水中向上浮一样,所以也称为气泡排序法。下面以一组待排序的数据演示冒泡排序的过程,假设有6个需要排序的数据序列如下:69,65,90,37,92,6...原创 2020-09-22 10:53:23 · 605 阅读 · 1 评论 -
算法十:DFS深度优先搜索(DFS子序列问题、迷宫问题、全排列)
深度优先搜索概述深度优先搜索和广度优先搜索一样,都是对图进行搜索的算法,目的也都是从起点开始搜索直到到达指定顶点(终点)。深度优先搜索会沿着一条路径不断往下搜索直到不能再继续为止,然后再折返,开始搜索下一条候补路径。DFS思想A为起点,G为终点。一开始我们在起点A上。将可以从A直达的三个顶点B、C、D设为下一步的候补顶点。从候补顶点中选出一个顶点。优先选择最新成为候补的点,如果几个顶点同时成为候补,那么可以从中随意选择一个。注:此处,候补顶点是用“后入先出”(LIFO)的方式来管理的,因此原创 2021-01-07 09:35:38 · 685 阅读 · 0 评论 -
算法十一——散列表hash(牺牲空间换时间,提高查找速度)附数字查找hash题、变变式题——字符串出现次数
在平均情况下,散列表执行各种操作的时间都为O(1)。O(1)被称为常量时间。你以前没有见过常量时间,它并不意味着马上,而是说不管散列表多大,所需的时间都相同这意味着无论散列表包含一个元素还是10亿个元素,从其中获取数据所需的时间都相同。实际上,你以前见过常量时间——从数组中获取一个元素所需的时间就是固定的:不管数组多大,从中获取一个元素所需的时间都是相同的。在平均情况下,散列表的速度确实很快。例一、对应的C++代码如下:#include<iostream>#include<原创 2020-10-26 11:15:52 · 678 阅读 · 0 评论 -
算法十二:BFS宽度优先搜索(迷宫问题)
迷宫问题C代码#include<stdio.h>typedef struct node{ int x; int y; int f; /*如果需要输出路径,则需要f */ int s; /* 步数 */ }node; int main(){ node que[2501]; int a[51][51] = {0}, book[51][51] = {0}; /* 右 下 左 上 */ int next[4][2] = {{0, 1}, {1, 0原创 2021-06-05 13:46:39 · 486 阅读 · 0 评论