10大算法
       

开始~~~


目录

  • 十大算法
    • 1.二分查找算法
      • 1.1基本介绍
      • 1.2代码
    • 2.分治算法
      • 2.1基本介绍
      • 2.2分治算法的基本步骤
      • 2.3汉诺塔游戏的思路分析
      • 2.4代码
    • 3.动态规划算法
      • 3.1应用场景
      • 3.2动态规划算法介绍
      • 3.3背包问题的思路分析
      • 3.4代码
    • 4.KMP算法
      • 4.1应用场景
      • 4.2暴力匹配算法
      • 4.3KMP算法介绍
      • 4.4KMP算法最佳应用-字符串匹配问题
    • 5.贪心算法
      • 5.1应用场景-集合覆盖问题
      • 5.2贪心算法介绍
      • 5.3贪心算法最佳应用-集合覆盖
    • 6.普里姆算法
      • 6.1应用场景-修路问题
      • 6.2最小生成树
      • 6.3普里姆算法介绍
      • 6.4解决修路问题
    • 7.克鲁斯卡尔算法
      • 7.1应用场景-公交站问题
      • 7.2克鲁斯卡尔算法介绍
      • 7.3克鲁斯卡尔最佳实践-公交站问题
  • 总结

十大算法

1.二分查找算法

1.1基本介绍

1)二分查找法只适用于从有序的数列中进行查找(比如数字和字母等),将数列排序后再进行查找。
       2)二分查找法的运行时间为对数时间O(㏒₂n) ,即查找到需要的目标位置最多只需要㏒₂n步,假设从[0,99]的队列(100个数,即n=100)中寻到目标数30,则需要查找步数为㏒₂100 , 即最多需要查找7次( 2^6 < 100 < 2^7)。

1.2代码

public static int binarySearch(int[] arr,int target){int left = 0;int right = arr.length - 1;while(left <= right){int mid = (left + right) / 2;if(arr[mid] == target){return mid;}else if(arr[mid] > target){right = mid - 1;}else{left = mid + 1;}}return -1;
}

2.分治算法

2.1基本介绍

分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……
       分治算法可以求解的一些经典问题:
       二分搜索、大整数乘法、棋盘覆盖、合并排序、快速排序、线性时间选择、最接近点对问题、循环赛日程表、汉诺塔

2.2分治算法的基本步骤

分治法在每一层递归上都有三个步骤:

1)分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题。
       2)解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题。
       3)合并:将各个子问题的解合并为原问题的解。

2.3汉诺塔游戏的思路分析

1)如果是有一个盘, A->C
       2)如果我们有 n >= 2 情况,我们总是可以看做是两个盘 ①最下边的盘 ②上面的盘
              先把 最上面的盘 A->B
              把最下边的盘 A->C
              把B塔的所有盘 从 B->C

2.4代码

public static void hanoiTower(int num,char a,char b,char c){//如果只一个盘if(num == 1){System.out.println("第1个盘从" + a + "->" + c);}else{//如果我们n>=2情况,我们总是可以看作是两个盘 1.最下边的一个盘  2.上面的所盘//1.先把上面的所盘A->B,移动过程使用到ChanoiTower(num - 1, a, c, b);//2.把最下面的盘A->CSystem.out.println("第" + num + "个盘从" + a + "->" + c);//3.把B塔的所盘从B->C,移动过程中使用到A塔hanoiTower(num - 1, b, a, c);}
}

3.动态规划算法

3.1应用场景

背包问题:有一个背包,容量为4磅 , 现有如下物品


       1)要求达到的目标为装入的背包的总价值最大,并且重量不超出
       2)要求装入的物品不能重复

3.2动态规划算法介绍

1)动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法。
       2)动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
       3)与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。( 即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解 )。
       4)动态规划可以通过填表的方式来逐步推进,得到最优解。

3.3背包问题的思路分析

3.4代码

public static void main(String[] args) {int[] w = {3,4,1};//物品的重量int[] val = {2000,3000,1500};//物品的价值int m = 4;//背包的容量int n = val.length;//物品的个数int[][] path = new int[n + 1][m + 1];int[][] v = new int[n + 1][m + 1];for (int i = 0; i < v.length; i++) {v[i][0] = 0;}for (int i = 0; i < v[0].length; i++) {v[0][i] = 0;}for (int i = 1; i < v.length; i++) {for (int j = 1; j < v[i].length; j++) {if (w[i - 1] > j){v[i][j] = v[i - 1][j];}else{if (v[i - 1][j] > val[i - 1] + v[i - 1][j - w[i - 1]]){v[i][j] = v[i - 1][j];}else{v[i][j] = val[i - 1] + v[i - 1][j - w[i - 1]];path[i][j] = 1;}}}}int i = path.length - 1;int j = path[0].length - 1;while (i > 0 && j > 0){if (path[i][j] == 1){System.out.printf("第%d个商品加入背包\n",i);j -= w[i - 1];}i--;}
}

4.KMP算法

4.1应用场景

字符串匹配问题:

1)有一个字符串 str1= ““硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好””,和一个子串 str2=“尚硅谷你尚硅你”。
       2)现在要判断 str1 是否含有 str2, 如果存在,就返回第一次出现的位置, 如果没有,则返回-1。

4.2暴力匹配算法

如果用暴力匹配的思路,并假设现在str1匹配到 i 位置,子串str2匹配到 j 位置,则有:

1)如果当前字符匹配成功(即str1[i] == str2[j]),则i++,j++,继续匹配下一个字符
       2)如果失配(即str1[i] ! = str2[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0
       3)用暴力方法解决的话就会有大量的回溯,每次只移动一位,若是不匹配,移动到下一位接着判断,浪费了大量的时间
       4)暴力匹配算法实现:

public static int violenceMatch(String str1,String str2){char[] s1 = str1.toCharArray();char[] s2 = str2.toCharArray();int s1Len = s1.length;int s2Len = s2.length;int i = 0;//i索引指向s1int j = 0;//i索引指向s2while(i < s1Len && j < s2Len){//保证匹配时,不越界if(s1[i] == s2[j]){//匹配i++;j++;}else{//没匹配成功i = i - (j - 1);j = 0;}}//判断是否匹配成功if(j == s2Len){return i - j;}return -1;
}

4.3KMP算法介绍

1)KMP是一个解决模式串在文本串是否出现过,如果出现过,最早出现的位置的经典算法
       2)KMP方法算法就利用之前判断过的信息,通过一个next数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过next数组找到,前面匹配过的位置,省去了大量的计算时间。

4.4KMP算法最佳应用-字符串匹配问题

有一个字符串 str1= “BBC ABCDAB ABCDABCDABDE”,和一个子串 str2="ABCDABD"现在要判断 str1 是否含有 str2, 如果存在,就返回第一次出现的位置, 如果没有,则返回-1
       要求:使用KMP算法完成判断,不能使用简单的暴力匹配算法

代码:

public static int kmpSearch(String str1,String str2,int[] next){//遍历for(int i = 0,j = 0;i < str1.length();i++){while(j > 0 && str1.charAt(i) != str2.charAt(j)){j = next[j - 1];}if(str1.charAt(i) == str2.charAt(j)){j++;}if(j == str2.length()){return i - j + 1;}}return -1;
}
//获取到一个字符串(子串)的部分匹配值表
public static int[] kmpNext(String dest){//创建一个next数组保存部分匹配值int[] next = new int[dest.length()];next[0] = 0;//如果字符串是长度为1部分匹配值就是0for(int i = 1,j = 0;i < dest.length();i++){//当dest.charAt(i) != dest.charAt(j),需要从next[j - 1]获取新的j//直到发现dest.charAt(i) == dest.charAt(j)成立才退出while(j > 0 && dest.charAt(i) != dest.charAt(j)){j = next[j - 1];}//当dest.charAt(i) == dest.charAt(j)满足时,部分匹配值就是+1if(dest.charAt(i) == dest.charAt(j)){j++;}next[i] = j;}return next;
}

5.贪心算法

5.1应用场景-集合覆盖问题

假设存在下面需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号。

5.2贪心算法介绍

1)贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法。
       2)贪婪算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果。

5.3贪心算法最佳应用-集合覆盖

1)假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号


       2)思路分析
       ①可以使用穷举法来实现,列出每个可能的广播台的集合。假设总的有n个广播台,则广播台的组合总共有2ⁿ -1 个,假设每秒可以计算10个子集


       ②使用贪婪算法,效率高
       1)遍历所有的广播电台, 找到一个覆盖了最多未覆盖的地区的电台(此电台可能包含一些已覆盖的地区,但没有关系)
       2)将这个电台加入到一个集合中(比如ArrayList), 想办法把该电台覆盖的地区在下次比较时去掉。
       3)重复第1步直到覆盖了全部的地区

4)思路图解:
       3)代码

//创建广播电台,放入到map
HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
HashSet<String> hashSet1 = new HashSet<>();
hashSet1.add("北京");
hashSet1.add("上海");
hashSet1.add("天津");
HashSet<String> hashSet2 = new HashSet<>();
hashSet2.add("广州");
hashSet2.add("北京");
hashSet2.add("深圳");
HashSet<String> hashSet3 = new HashSet<>();
hashSet3.add("成都");
hashSet3.add("上海");
hashSet3.add("杭州");
HashSet<String> hashSet4 = new HashSet<>();
hashSet4.add("上海");
hashSet4.add("天津");
HashSet<String> hashSet5 = new HashSet<>();
hashSet5.add("杭州");
hashSet5.add("大连");broadcasts.put("K1", hashSet1);
broadcasts.put("K2", hashSet2);
broadcasts.put("K3", hashSet3);
broadcasts.put("K4", hashSet4);
broadcasts.put("K5", hashSet5);//allAreas存放所的地区
HashSet<String> allAreas = new HashSet<>();
allAreas.add("北京");
allAreas.add("上海");
allAreas.add("天津");
allAreas.add("广州");
allAreas.add("深圳");
allAreas.add("成都");
allAreas.add("杭州");
allAreas.add("大连");//创建一个ArrayList,存放择的电台集合
ArrayList<String> selects = new ArrayList<>();//定义一个临时的集合,在遍历的过程中,存放电台覆盖的区域和当前还没覆盖的地区的交集
HashSet<String> tempSet = new HashSet<>();
//定义给maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key
//如果maxKey不为null,则加入到selects中
String maxKey;
int maxSize;
while(allAreas.size() != 0){//如allAreas不为0,则表示还没覆盖到所的地区maxKey = null;//遍历broadcasts,取出keyfor(String key : broadcasts.keySet()){tempSet.clear();//当前这个key能够覆盖的地区HashSet<String> areas = broadcasts.get(key);tempSet.addAll(areas);//求出tempSet与allAreas集合的交集,交集会赋给tempSettempSet.retainAll(allAreas);if(maxKey == null){maxSize = 0;}else{HashSet<String> maxSet = broadcasts.get(maxKey);maxSet.retainAll(allAreas);maxSize = maxSet.size();}
//              if(tempSet.size() > 0 && (maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())){if(tempSet.size() > 0 && (maxKey == null || tempSet.size() > maxSize)){maxKey = key;}}if(maxKey != null){selects.add(maxKey);allAreas.removeAll(broadcasts.get(maxKey));}
}
System.out.println(selects);

6.普里姆算法

6.1应用场景-修路问题

1)胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通
       2)各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里
       问:如何修路保证各个村庄都能连通,并且总的修建公路总里程最短
       正确的思路,就是尽可能的选择少的路线,并且每条路线最小,保证总里程数最少

6.2最小生成树

修路问题本质就是就是最小生成树问题

最小生成树:
       1)给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树
       2)N个顶点,一定有N-1条边
       3)包含全部顶点
       4)N-1条边都在图中
       如图:
       5)求最小生成树的算法主要是普里姆算法和克鲁斯卡尔算法

6.3普里姆算法介绍

1)普利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的极小连通子图。
       2)普利姆的算法如下:
       ①设G=(V,E)是连通网,T=(U,D)是最小生成树,V,U是顶点集合,E,D是边的集合
       ②若从顶点u开始构造最小生成树,则从集合V中取出顶点u放入集合U中,标记顶点v的visited[u]=1
       ③若集合U中顶点ui与集合V-U中的顶点vj之间存在边,则寻找这些边中权值最小的边,但不能构成回路,将顶点vj加入集合U中
       ④将边(ui,vj)加入集合D中,标记visited[vj]=1
       ⑤重复步骤②,直到U与V相等,即所有顶点都被标记为访问过,此时D中有n-1条边

6.4解决修路问题

       1)有胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通
       2)各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里
       3)问:如何修路保证各个村庄都能连通,并且总的修建公路总里程最短?
       4)代码:

public class PrimAlgorithm {public static void main(String[] args) {char[] data = new char[]{'A','B','C','D','E','F','G'};int verxs = data.length;//邻接矩阵的关系使用二维数组表示,用10000表示两个点不联通int[][] weight = new int[][]{{10000,5,7,10000,10000,10000,2},{5,10000,10000,9,10000,10000,3},{7,10000,10000,10000,8,10000,10000},{10000,9,10000,10000,10000,4,10000},{10000,10000,8,10000,10000,5,4},{10000,10000,10000,4,5,10000,6},{2,3,10000,10000,4,6,10000}};//创建Graph对象MGraph graph = new MGraph(verxs);MinTree minTree = new MinTree();minTree.createGraph(graph, verxs, data, weight);//输出minTree.showGraph(graph);minTree.prim(graph, 0);}
}// 创建最小生成树->村庄的图
class MinTree {/*** * @Description 创建图的邻接矩阵* @author jiatianyu * @date 2021年3月18日下午2:23:02 * @param graph 图对象* @param verxs 图对应的顶点个数* @param data 图的各个顶点的值* @param weight 图的邻接矩阵*/public void createGraph(MGraph graph, int verxs, char data[], int[][] weight) {int i,j;for(i = 0;i < verxs;i++){//顶点graph.data[i] = data[i];for(j = 0;j < verxs;j++){graph.weight[i][j] = weight[i][j];}}}//显示图的结构public void showGraph(MGraph graph){for(int[] link : graph.weight){System.out.println(Arrays.toString(link));}}public void prim(MGraph graph,int v){//visited[] 标记点(顶点)是否被访问过int[] visited = new int[graph.verxs];//把当前这个结点标记为已访问visited[v] = 1;//h1和h2记录两个顶点的下标int h1 = -1;int h2 = -1;int minWeight = 10000;//将minWeight初始成一个大数,后面在遍历过程中会被替换for(int k = 1;k < graph.verxs;k++){//因为graph.verxs个顶点,总共需要graph.verxs - 1个边//每一次生成的子图,和那个结点的距离最近for(int i = 0;i < graph.verxs;i++){//i结点表示被访问过的结点for(int j = 0;j < graph.verxs;j++){//j结点表示没被访问过的结点if(visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight){//替换minWeightminWeight = graph.weight[i][j];h1 = i;h2 = j;}}}//找到一条边最小System.out.println("边<" + graph.data[h1] + "," + graph.data[h2] + ">权值:" + minWeight);//将当前这个结点标记为已经访问visited[h2] = 1;//minWeight重新设置成最大值10000minWeight = 10000;}}
}
class MGraph {int verxs;// 表示图的结点个数char[] data;// 存放结点数据int[][] weight;// 存放边,即邻接矩阵public MGraph(int verxs) {this.verxs = verxs;data = new char[verxs];weight = new int[verxs][verxs];}
}

7.克鲁斯卡尔算法

7.1应用场景-公交站问题

       1)某城市新增7个站点(A, B, C, D, E, F, G) ,现在需要修路把7个站点连通
       2)各个站点的距离用边线表示(权) ,比如 A – B 距离 12公里
       问:如何修路保证各个站点都能连通,并且总的修建公路总里程最短?

7.2克鲁斯卡尔算法介绍

1)克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法。
       2)基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路
       3)具体做法:首先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中不产生回路,直至森林变成一棵树为止

7.3克鲁斯卡尔最佳实践-公交站问题

       1)有北京有新增7个站点(A, B, C, D, E, F, G) ,现在需要修路把7个站点连通
       2)各个站点的距离用边线表示(权) ,比如 A – B 距离 12公里
       3)问:如何修路保证各个站点都能连通,并且总的修建公路总里程最短?
       4)代码:

public class KruskalCase {private int edgeNum;//边的个数private char[] vertexs;//顶点数组private int[][] matrix;//邻接矩阵//使用INF表示两个顶点不能联通private static final int INF = Integer.MAX_VALUE;public static void main(String[] args) {char[] vertexs = {'A','B','C','D','E','F','G'};int matrix[][] = {{0,12,INF,INF,INF,16,14},{12,0,10,INF,INF,7,INF},{INF,10,0,3,5,6,INF},{INF,INF,3,0,4,INF,INF},{INF,INF,5,4,0,2,8},{16,7,6,INF,2,0,9},{14,INF,INF,INF,8,9,0}};//创建KruskalCase对象实例KruskalCase kruskalCase = new KruskalCase(vertexs, matrix);EData[] edges = kruskalCase.getEdges();kruskalCase.sortEdges(edges);kruskalCase.kruskal();}//构造器public KruskalCase(char[] vertexs,int[][] matrix){//初始化顶点数和边的个数int vlen = vertexs.length;//初始化顶点,复制拷贝的方式this.vertexs = new char[vlen];for(int i = 0;i < vertexs.length;i++){this.vertexs[i] = vertexs[i];}//初始化边,使用的是复制拷贝的方式this.matrix = new int[vlen][vlen];for(int i = 0;i < vlen;i++){for(int j = 0;j < vlen;j++){this.matrix[i][j] = matrix[i][j];}}//统计边for(int i = 0;i < vlen;i++){for(int j = i + 1;j < vlen;j++){if(this.matrix[i][j] != INF){edgeNum++;}}}}public void kruskal(){int index = 0;//表示最后结果数组的索引int[] ends = new int[edgeNum];//用于保存"已最小生成树"中的每个顶点在最小生成树中的终点//创建结果数组,保存最后的最小生成树EData[] rets = new EData[edgeNum];//获取图中所的边的集合,一共有12边EData[] edges = getEdges();sortEdges(edges);//遍历edges数组,将边添加到最小生成树中时,判断准备加入的边是否形成了回路,如果没,就加入rets,否则不能加入for(int i = 0;i < edgeNum;i++){//获取到第i条边的第一个顶点(起点)int p1 = getPosition(edges[i].start);//p1 = 4//获取到第i条边的第2个顶点int p2 = getPosition(edges[i].end);//p2 = 5//获取p1这个顶点在已最小生成树中的终点int m = getEnd(ends,p1);//m = 4;//获取p2这个顶点在已最小生成树中的终点int n = getEnd(ends,p2);//n = 5;//是否构成回路if(m != n){//没构成回路ends[m] = n;//设置m在"已最小生成树"中的终点rets[index++] = edges[i];}}//打印retsSystem.out.println("最小生成树为:");for(int i = 0;i < index;i++){System.out.println(rets[i]);}}//打印邻接矩阵public void print(){System.out.println("邻接矩阵为:\n");for(int i = 0;i < vertexs.length;i++){for(int j = 0;j < vertexs.length;j++){System.out.printf("%12d\t",matrix[i][j]);}System.out.println();//换行}}//对边进行排序处理,冒泡排序private void sortEdges(EData[] edges){EData temp = null;for(int i = 0;i < edges.length - 1;i++){for(int j = 0;j < edges.length - 1 -i;j++){if(edges[j].getWeight() > edges[j + 1].getWeight()){temp = edges[j];edges[j] = edges[j + 1];edges[j + 1] = temp;}}}}/*** * @Description  * @author jiatianyu * @date 2021年3月18日下午9:44:25 * @param ch ch:顶点值,比如'A','B'* @return 顶点ch对应的下标,如果找不到,返回-1*/private int getPosition(char ch){for(int i = 0;i < vertexs.length;i++){if(vertexs[i] == ch){return i;}}return -1;}private EData[] getEdges(){int index = 0;EData[] edges = new EData[edgeNum];for(int i = 0;i < vertexs.length;i++){for(int j = i + 1;j < vertexs.length;j++){if(matrix[i][j] != INF){edges[index++] = new EData(vertexs[i], vertexs[j], matrix[i][j]);}}}return edges;}/*** * @Description 获取下标为i的顶点的终点,用于判断两个顶点的终点是否相同* @author jiatianyu * @date 2021年3月19日上午11:55:43 * @param ends 数组记录了各个顶点的对应的终点是哪个,ends数组是在遍历过程中,逐步形成的* @param i 表示传入的顶点对应的下标* @return 返回下标为i的顶点对应的终点的下标*/private int getEnd(int[] ends,int i){while(ends[i] != 0){i = ends[i];}return i;}
}//创建一个类EData,它的对象实例表示一条边
class EData{char start;//边的一个点char end;//边的另一个点int weight;//边的权值//构造器public EData(char start, char end, int weight) {super();this.start = start;this.end = end;this.weight = weight;}//重写toString,便于输出边@Overridepublic String toString() {return "EData [start=" + start + ", end=" + end + ", weight=" + weight + "]";}public char getStart() {return start;}public void setStart(char start) {this.start = start;}public char getEnd() {return end;}public void setEnd(char end) {this.end = end;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}
}

总结

To be continued~~,JavaEE部分

数据结构与算法weeks05相关推荐

  1. Python3-Cookbook总结 - 第一章:数据结构和算法

    第一章:数据结构和算法 Python 提供了大量的内置数据结构,包括列表,集合以及字典.大多数情况下使用这些数据结构是很简单的. 但是,我们也会经常碰到到诸如查询,排序和过滤等等这些普遍存在的问题. ...

  2. 推荐一个关于.NET平台数据结构和算法的好项目

    http://www.codeplex.com/NGenerics 这是一个类库,它提供了标准的.NET框架没有实现的通用的数据结构和算法.值得大家研究. 转载于:https://www.cnblog ...

  3. 数据结构和算法:(3)3.1线性表的顺序存储结构

    -----------------------1.线性表基础操作------------------------ 线性表:(List)由零个或多个数据元素组成的有限序列. 首先他是一个序列,元素之间是 ...

  4. weiss数据结构和算法书的使用说明

    <数据结构与算法分析 C语言描述>Mark Allen Weiss著,冯舜玺译,机械工业出版社.Weiss教授的经典教材三部曲之一,其中的C语言描述版本,也就是本书,被称为20世纪最重要的 ...

  5. 数据结构和算法 -- 学习导图

    数据结构和算法 是作为程序员写出高效代码的基础,为了今后的两年在高效代码之路上持续精进,将按照此学习导图进行 算法和数据结构的刻意练习,同时也希望为同样有高效代码追求的伙伴们提供一条学习路径,共同进步 ...

  6. Java数据结构与算法(第四章栈和队列)

    2019独角兽企业重金招聘Python工程师标准>>> 本章涉及的三种数据存储类型:栈.队列和优先级队列. 不同类型的结构 程序员的工具 数组是已经介绍过的数据存储结构,和其他结构( ...

  7. python数据结构与算法总结

    python常用的数据结构与算法就分享到此处,本月涉及数据结构与算法的内容有如下文章: <数据结构和算法对python意味着什么?> <顺序表数据结构在python中的应用> ...

  8. 学习JavaScript数据结构与算法(一):栈与队列

    本系列的第一篇文章: 学习JavaScript数据结构与算法(一),栈与队列 第二篇文章:学习JavaScript数据结构与算法(二):链表 第三篇文章:学习JavaScript数据结构与算法(三): ...

  9. MySQL索引背后的数据结构及算法原理【转】

    http://blog.codinglabs.org/articles/theory-of-mysql-index.html MySQL索引背后的数据结构及算法原理[转] 摘要 本文以MySQL数据库 ...

最新文章

  1. 【Java】反射( reflection)机制 详解
  2. python编写爬虫的步骤-python学习: 写网络爬虫程序的三个难点
  3. Linux运维人员必会开源运维工具体系
  4. Ubuntu安装程序出现“Sub-process usrbindpkg returned an error code (1)”的问题
  5. Greenplum数据库(GPDB)初识
  6. vs五子棋c语言代码,五子棋代码C语言版.doc
  7. python中的string模块_有没有可能模仿Python中的string模块?
  8. auth 认证组件的补充
  9. Vue检测当前是否处于mock模式
  10. 大一计算机应用基础答案李小艳,13级幼师班期末考试计算机试题A卷
  11. SQLPro Studio mac如何链接MYSQL?
  12. iOS Crash文件的解析
  13. Nvelocity 第二章 注释语法
  14. shell 封装方法_反弹shell逃逸基于execve的命令监控(上)
  15. 浅谈非数学类全国大学生数学竞赛
  16. 2007左右美国程序员工资大概样子
  17. Java并发25 ThreadFactory使用的必要性
  18. 学习管理系统 LMS
  19. autocad2014 转pdf并保存多页
  20. 保姆级给电脑分盘,和合并两个盘

热门文章

  1. arm-openwrt-linux-musl 交叉编译cyassl
  2. w10设置文件服务器,w10设置文件服务器
  3. 液压伺服比例控制及PLC应用—学习笔记1
  4. 这应该是最通俗易懂的PyEcharts的操作指南!
  5. 13 常见CHIP封装的创建
  6. 30 分钟看懂 CatBoost(Python代码)
  7. 重庆抵扣联信息系统服务器,增值税专用发票抵扣联信息采集系统
  8. android可以剪辑代码的控件,Android 仿抖音视频裁剪范围选择控件,支持本地视频和网络视频...
  9. 基于springboot车辆充电桩设计与实现的源码+文档
  10. Android 使用OpenCV 进行书法字体重影比对