算法
文章平均质量分 76
刷算法是这个世界上最让人开心的事吧~
还记得樱花正开~
这个作者很懒,什么都没留下…
展开
-
二叉树遍历 递归/非递归/morris
递归 非递归 Morris原创 2022-03-13 16:32:52 · 2331 阅读 · 0 评论 -
树状数组的应用
1 统计序列中在元素左边比该元素小的元素个数#include<stdio.h>#include<string.h>#define lowbit(i) ((i)&(-i))const int maxn=100010;int c[maxn]; //树状数组 //getSum函数返回前x个整数之和 int getSum(int x){ int sum=0; //记录和 for(int i=x;i>0;i-=lowbit(i)){ sum+=c[原创 2020-08-28 13:43:11 · 103 阅读 · 0 评论 -
KMP算法
string匹配pattern#include<stdio.h>#include<string.h> const int maxn=1010;int next[maxn]; //所求最长相等前后缀中前缀最后一位的下标 //getNext求解长度为len的字符串s的next数组 void getNext(char s[],int len){ int j=-1; next[0]=-1; for(int i=0;i<len;i++){ //求解next[1]-n原创 2020-08-24 20:21:04 · 129 阅读 · 0 评论 -
hash处理字符串问题
1 判断字符串是否相等#include<iostream>#include<string>#include<vector>#include<algorithm>using namespace std;const int mod=1000000007; //mod为计算hash值时的模数 const int p=10000019; //p为计算hash值时的进制数 vector<int> ans;//字符串hashlong原创 2020-08-24 13:11:03 · 270 阅读 · 0 评论 -
动态规划
1 动态规划递推写法:自底向上;递归写法:自顶向下一个问题必须拥有重叠子问题和最优子结构,才能用动态规划去解决。1.1 分治与动态规划共同点:都是将问题分解为子问题,然后合并子问题的解得到原问题的解。不同点:分治法解决的问题不拥有重叠子问题,而动态规划解决的问题拥有重叠子问题;分治法解决的问题不一定是最优化问题,而动态规划解决的问题一定是最优化问题。1.2 贪心与动态规划共同点:都要求原问题必须拥有最优子结构不同点:动态规划是从边界开始向上得到目标问题的解,贪心不一定得到最优原创 2020-08-24 09:50:09 · 219 阅读 · 0 评论 -
拓扑排序和关键路径
#include<stdio.h>#include<string.h>#include<vector>#include<queue>#include<stack>using namespace std;struct Node{ int v,w;};const int maxv=1010;vector<Node> g[maxv]; //邻接表 int n,m,indegree[maxv]; //顶点数、边数、.原创 2020-08-23 16:57:45 · 183 阅读 · 2 评论 -
最小生成树——Kruskal算法
#include<stdio.h>#include<algorithm>using namespace std;const int maxe=1010;const int maxv=110;struct edge{ int u,v; //边的两个端点编号 int cost; //边权 }e[maxe];bool cmp(edge a,edge b){ return a.cost<b.cost;}int father[maxv];int fi.原创 2020-08-23 10:59:24 · 130 阅读 · 0 评论 -
并查集
1 返回根结点//findFather函数返回元素x所在集合的根结点int findFather(int x){ while(x!=father[x]){ //如果不是根结点,继续循环 x=father[x]; //获得自己的父亲结点 } return x;} 2 合并两个集合//合并两个集合void Union(int a,int b){ int faA=findFather(a); //查找a的根结点 int faB=findFather(b); //查找b的根原创 2020-08-23 10:30:06 · 75 阅读 · 0 评论 -
最小生成树——Prim算法
1 邻接矩阵版const int maxv=1000; //最大顶点数const int inf=1000000000;//邻接矩阵版int n,m,g[maxv][maxv];int d[maxv]; //顶点与集合s的最短距离 bool vis[maxv]={false}; //标记已访问数组 int prim1(){ //默认0号为初始点,函数返回最小生成树的边权之和 fill(d,d+maxv,inf); d[0]=0; //只有0号顶点到集合s的距离为0,其余全为inf原创 2020-08-23 10:11:55 · 110 阅读 · 0 评论 -
最短路径——Floyd算法
#include<cstdio>#include<algorithm>using namespace std;const int inf=100000000;const int maxv=200;int n,m; //n是顶点数,m是边数 int dis[maxv][maxv];void floyd(){ for(int k=0;k<n;k++){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++){.原创 2020-08-22 20:51:17 · 99 阅读 · 0 评论 -
最短路径——Dijkstra算法
1 邻接矩阵版const int maxv=1000;const int inf=1000000000;//邻接矩阵版int n,m,s,g[maxv][maxv]; //n为顶点数,m为边数,s为起点,maxv为最大顶点数 int d[maxv]; //起点到各点的最短路径长度 bool vis[maxv]={false}; //标记是否已访问 void dijkstra1(int s){ //s为起点 fill(d,d+maxv,inf); //fill函数将整个d数组赋为原创 2020-08-22 17:30:47 · 182 阅读 · 0 评论 -
图的遍历DFS和BFS
1 DFS1.1 邻接矩阵版const int maxv=1000; //最大顶点数const int inf=1000000000; //设inf为一个很大的数//邻接矩阵版int n,g[maxv][maxv]; //n为顶点数,maxv为最大顶点数bool vis[maxv]={false}; //如果顶点i被访问,则vis[i]==true,初始为falsevoid dfs(int u,int depth){ //u为当前访问的顶点标号,depth为深度 vis[u]=t原创 2020-08-21 23:51:20 · 129 阅读 · 0 评论 -
哈夫曼树和哈夫曼编码
1 树的带权路径长度WPL带权路径长度:叶子结点的权值乘以其路径长度的结果树的带权路径长度:这棵树所有叶子结点的带权路径长度之和2 哈夫曼树带权路径长度最小的树哈夫曼树可以不唯一,但是最小带权路径长度一定是唯一的可以使用优先队列实现堆,例子如下:#include<stdio.h>#include<queue>using namespace std;//代表小顶堆的优先队列 priority_queue<long long,vector&l原创 2020-08-21 22:30:47 · 307 阅读 · 0 评论 -
堆的操作和堆排序
1 向下调整//对heap数组在[low,high]范围进行向下调整 void downAdjust(int low,int high){ int i=low,j=i*2; //i为欲调整结点,j为其左孩子 while(j<=high){ //存在孩子结点 //如果右孩子存在,且右孩子的值大于左孩子 if(j+1<=high&&heap[j+1]>heap[j]) j=j+1; //j存储右孩子下标 //如果孩子中最大的权值比欲调整结点i大原创 2020-08-21 22:01:07 · 114 阅读 · 0 评论 -
二叉查找树BST
1 查找//search函数查找二叉查找树中数据域为x的结点void search(node* root,int x){ if(root==NULL){ printf("search failed\n"); return; } if(x==root->data){ printf("%d\n",root->data); }else if(x<root->data){ search(root->lchild,x); }else{ search(原创 2020-08-21 14:02:58 · 78 阅读 · 0 评论 -
归并排序、快速排序、随机数
1 归并排序1.1 递归实现const int maxn=100;//将数组A的[l1,r1]与[l2,r2]区间合并为有序区间 void merge2(int A[],int l1,int r1,int l2,int r2){ int i=l1,j=l2; int temp[maxn],index=0; while(i<=r1&&j<=r2){ if(A[i]<=A[j]) temp[index++]=A[i++]; else te原创 2020-08-21 11:38:51 · 353 阅读 · 0 评论 -
平衡二叉树AVL
1 结点定义//平衡二叉树AVL struct node{ int v,height; node *lchild,*rchild;};2 创建新结点//创建新结点 node* newNode(int v){ node* Node=new node; Node->v=v; Node->height=1; //结点高度初始化为1 Node->lchild=Node->rchild=NULL; return Node;}3 获取结点root所在子原创 2020-08-20 18:18:24 · 113 阅读 · 0 评论 -
二叉树的创建、查找、插入、遍历
1 二叉树结构struct node{ int data; //数据域 int layer; //层次 node* lchild; //指向左子树根结点的指针 node* rchild; //指向右子树根结点的指针 };2 新建结点//新建结点,v为结点权值 node* newNode(int v){ node* Node=new node; Node->data=v; Node->lchild=Node->rchild=NULL; retur原创 2020-08-19 19:52:53 · 390 阅读 · 0 评论 -
快速幂——递归和迭代两种写法
1 递归写法//递归写法 ll binaryPow1(ll a,ll b,ll m){ if(b==0) return 1; //如果b为0,那么a^0=1 //b为奇数,转换为b-1 if(b%1==1) return a*binaryPow1(a,b-1,m)%m; else{ ll mul=binaryPow1(a,b/2,m); return mul*mul%m; } }2 迭代写法//迭代写法ll binaryPow2(ll a,ll b,ll m){原创 2020-08-19 11:36:24 · 186 阅读 · 0 评论 -
二分法
1 整数二分查找//A[]为严格递增序列,left为二分下界,right为二分上界,x为欲查询的数//二分区间为左闭右闭的[left,right],传入的初值为[0,n-1]int binarySearch(int A[],int left,int right,int x){ int mid; //mid为left和right的中点 while(left<=right){ mid=(left+right)/2; if(A[mid]==x) return mid; else i原创 2020-08-19 11:17:17 · 243 阅读 · 0 评论 -
区间贪心算法
求不相交区间的个数输入若干个区间的x和y端点#include<stdio.h>#include<algorithm>using namespace std;const int maxn=110;struct Inteval{ int x,y; //开区间左右端点 }I[maxn];bool cmp(Inteval a,Inteval b){ if(a.x!=b.x) return a.x>b.x; //先按左端点从大到小排序 else ret.原创 2020-08-19 10:20:41 · 143 阅读 · 0 评论 -
递归——数的全排列和n皇后问题
1 数的全排列#include<stdio.h>const int maxn=11;//p为当前排列,hashTable记录整数x是否已经在p中 int n,p[maxn],hashTable[maxn]={false};//当前处理排列的第index号位void generatep(int index){ if(index==n+1){ //递归边界,已处理完排列的1-n位 for(int i=1;i<=n;i++) printf("%d",p[i]);原创 2020-08-19 10:04:58 · 140 阅读 · 0 评论 -
广度优先搜索(BFS)——寻找矩阵中“1”的块数
输入6 70 1 1 1 0 0 10 0 1 0 0 0 00 0 0 0 1 0 00 0 0 1 1 1 01 1 1 0 1 0 01 1 1 1 0 0 0输出4代码#include<stdio.h>#include<queue>using namespace std;const int maxn=100;struct node{ int x,y; //位置(x,y) }Node;int n,m; //矩阵大小n.原创 2020-08-18 23:40:42 · 332 阅读 · 0 评论 -
链表的操作和动态内存分配
1 动态内存分配1.1 malloc//malloc函数动态申请内存,返回类型是申请的同变量类型的指针//如果申请失败,则返回空指针NULL typename* p1=(typename*)malloc(sizeof(typename));//对应malloc的内存释放free(p1); 1.2 new//new运算符申请动态空间//如果申请失败,则会启动C++异常机制处理 typename* p2=new typename; //对应new的内存释放delete(p2)原创 2020-08-18 18:07:31 · 2125 阅读 · 0 评论 -
栈的应用——四则运算表达式求值
#include<stdio.h>#include<iostream>#include<string>#include<stack>#include<queue>#include<map>using namespace std;struct node{ double num; //操作数 char op; //操作符 bool flag; //true表示是操作数,false表示是操作符 };strin.原创 2020-08-18 16:54:04 · 112 阅读 · 0 评论 -
用递归实现全排列数的输出
#include<stdio.h>const int maxn=11;//p为当前排列,hashTable记录整数x是否已经在p中 int n,p[maxn],hashTable[maxn]={false};//当前处理排列的第index号位void generatep(int index){ if(index==n+1){ //递归边界,已处理完排列的1-n位 for(int i=1;i<=n;i++) printf("%d",p[i]); printf(.原创 2020-08-16 22:47:53 · 317 阅读 · 0 评论 -
散列函数及冲突处理方法
1 散列将元素通过一个函数转换为整数,使得该整数可以尽量唯一地代表这个元素,其中这个转换函数称为散列函数H2 散列函数2.1 直接定址法恒等变换H(key)=key,或是线性变换H(key)=a*key+b2.2 平方取中法取key的平方的中间若干位作为hash值(很少用)2.3 除留余数法把key除以一个数mod得到的余数作为hash值的方法,H(key)=key%mod。通过这个方法可以把很大的数转换为不超过mod的整数,这样就可以把它作为可行的数组下标。当mod原创 2020-08-16 18:13:30 · 694 阅读 · 0 评论 -
组合数
#include<stdio.h>//在n个里选择m个 long long cal(long long n,long long m){ //可能会有中间变量溢出 long long ans=1; for(long long i=1;i<=n;i++) ans*=i; for(long long i=1;i<=m;i++) ans/=i; for(long long i=1;i<=n-m;i++) ans/=i; return ans;}lo.原创 2020-08-11 17:52:37 · 96 阅读 · 0 评论 -
阶乘质因子的计算——递归和非递归两种方法
#include<stdio.h>int cal(int n,int p){ //使用递归方法实现 if(n<p) return 0; //n<p时1-n中不可能有质因子p return n/p+cal(n/p,p); //返回n/p加上(n/p)!中的质因子p的个数 }int cal2(int n,int p){ int r=0; while(n/p){ r+=n/p; n/=p; } return r;}int main(){ in.原创 2020-08-11 15:31:35 · 230 阅读 · 0 评论 -
大整数运算
#include<stdio.h>#include<string.h>int r=0; //余数 struct bign{ int d[1000]; int len; bign(){ memset(d,0,sizeof(d)); len=0; }};bign change(char str[]){ //将字符数组转换成bign bign a; a.len=strlen(str); for(int i=0;i<a.len;i++){ .原创 2020-08-11 15:07:55 · 216 阅读 · 0 评论 -
素数的判断和素数表的获取
用两个数组分别存入素数和是否为素数的判断#include<stdio.h>#include<math.h>bool isPrime(int n){ //素数的判断 if(n<=1) return false; for(int i=2;i<(int)sqrt(1.0*n);i++){ if(n%i==0) return false; } return true;}const int maxn=101; //表长int prime[ma原创 2020-08-09 11:50:10 · 115 阅读 · 0 评论 -
分数的四则运算——用结构体实现
#include<stdio.h>#include<algorithm> struct Fraction{ //分数 int up,down; //分子、分母 Fraction(){} Fraction(int _up,int _down){ up=_up; down=_down; } };int gcd(int a,int b){ if(b==0) return a; else return gcd(b,a%b);} Fraction.原创 2020-08-09 11:35:09 · 1326 阅读 · 0 评论 -
最大公约数最小公倍数
#include<stdio.h>int gcd(int a,int b){ if(b==0) return a; else return gcd(b,a%b);}int lcm(int a,int b){ int temp=gcd(a,b); return a/temp*b;} int main(){ int a,b; scanf("%d%d",&a,&b); printf("gcd(%d,%d)=%d\n",a,b,gcd(a,b)).原创 2020-08-09 11:10:22 · 66 阅读 · 0 评论 -
C++标准模板库容器的常见用法
1.vector1.1 定义相当于是一维的变长数组vector<typename> name;1.2 元素访问下标访问 vi[index] 迭代器访问 vector<typename>::iterator it;1.3 常用函数push_back(x)在vector后面添加一个元素x,时间复杂度O(1) pop_back()删除vector尾元素,时间复杂度O(1) size()获得vector中元素的个数,时间复杂度O(1) clear()清空v原创 2020-08-09 09:37:41 · 225 阅读 · 0 评论 -
C++中的string学习
#include<stdio.h>#include<iostream>#include<string>using namespace std;int main(){ string s="zhuyan",s2; //通过下标访问 for(int i=0;i<s.length();i++) printf("%c",s[i]); printf("\n"); //C++中可直接输出 cout<<s<<endl; /.原创 2020-08-06 20:24:45 · 98 阅读 · 0 评论 -
stl中的queue、map、set、deque、list
1 queue#include<iostream>#include<queue>using namespace std;int main(){ queue<int> q; q.push(5); q.push(6); cout<<q.back()<<endl; //back是队尾元素 cout<<q.front()<<endl; //front是队头元素 q.pop(); cout<&l原创 2020-08-06 15:34:25 · 105 阅读 · 0 评论 -
sstream数据类型转换的使用方法
#include<iostream>#include<algorithm>#include<sstream>using namespace std;int main(){ //字符串转数字 //方法1 stringstream ss; string s="1234"; int i; ss<<s; ss>>i; cout<<i<<endl; //方法2 //stoi(字符串,起始位置,n.原创 2020-08-06 10:24:33 · 516 阅读 · 0 评论 -
stl中的stack学习
#include<iostream>#include<algorithm>#include<stack>#include<sstream>using namespace std;//十进制转二进制 int itob(int decimal){ stack<int> s; int res=0; while(decimal!=0){ s.push(decimal%2); decimal/=2; } while(!s..原创 2020-08-06 09:42:45 · 104 阅读 · 0 评论 -
stl中的vector学习
#include<iostream>#include<algorithm>#include<vector>using namespace std;int main(){ //vector相当于数组,模板类型相当于存放的内容 vector<int> v; //定义一个空vector vector<int> v2(4); //一个参数时,表示这个vector的大小是4 ,初始化为0 vector<int> v3(2.原创 2020-08-06 09:41:48 · 114 阅读 · 0 评论 -
冒泡排序、选择排序、插入排序
#include<stdio.h>//冒泡排序 void bubbleSort(int a[],int n){ int i,j,temp; for(i=0;i<n;i++){ for(j=0;j<n-i-1;j++){ if(a[j]>a[j+1]){ temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } }}//选择排序 void selectSort(int a[],int n){.原创 2020-08-04 21:30:00 · 110 阅读 · 0 评论