算法&数据结构
文章平均质量分 69
___Blue_H
0和1的世界简单一点
展开
-
Insertion Sort(插入排序)
算法思想 一个拥有若干个元素的序列,将其分为有序和无序的两部分(第一个元素视为有序),每次从无序部分中抽出一个元素,将其按指定关键字插入到有序部分中。源码C/C++void InsertionSort (std::vector<int> &vec){ if (vec.size() <= 1) return ; ...原创 2017-09-28 22:17:32 · 763 阅读 · 0 评论 -
快速排序优化
快速排序是一种以分治为基本思想的排序算法,它将待排序数组分成两个子数组,将两部分再独立地排序。其中涉及到三个重要操作:选择基准元素、切分、对切分得到的子数组进行快排(分治)。因此对快速排序的优化也应针对这三部分进行。优化基准元素选择 快速排序最理想的情况是每次都能将序列切分成相同大小的两部分,因此切分所用的基准元素如何选择就成了影响算法性能的关键。最简单的实现就是...原创 2018-10-14 12:25:15 · 435 阅读 · 0 评论 -
二叉搜索树结点的查找、插入、删除
二叉搜索树(Binary Search Tree,BST),要么是一颗空树,要么是一颗具有如下性质的二叉树:对于二叉搜索树的任意结点来说,若它的左子树非空,则左子树上所有结点的值均小于它的值; 若它的右子树不空,则右子树上所有结点的值均大于它的值; 它的左、右子树也分别为二叉搜索树。 定义一颗二叉搜索树的结点结构如下:struct BST_Node{ ...原创 2018-10-16 18:29:20 · 1036 阅读 · 0 评论 -
无向图及其深度优先搜索和广度优先搜索
无向图图(Graph)是表示事物与事物之间的关系的数学对象,是数学领域的重要分支——图论(Graph Theory)的研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。无向图中边(edge)仅仅是两个顶点(vertex)之间的连接,是比较简单的图。我们定义无向图的结构如...原创 2018-10-19 21:46:44 · 4491 阅读 · 0 评论 -
红黑树及其插入、删除操作
在二叉搜索树中,基本操作如结点的插入、删除、查找的性能上界都得不到保证,原因在于二叉搜索树的构造依赖于其结点值的插入顺序,最坏情况下二叉搜索树会退化为单链表(如下图所示)。因此我们需要对二叉搜索树做出一些改进和限制,从而使其拥有更好更稳定的性能上界保证。红黑树就是一种自平衡的二叉搜索树。定义红黑树除了满足二叉搜索树的性质以外,还有以下性质:(1)红黑树的结点都是带有“颜色”属性的,...原创 2018-10-19 13:57:05 · 2184 阅读 · 0 评论 -
强连通分量求解算法
强连通分量在有向图中,如果顶点v和w相互可达,则称这两个顶点之间强连通。一幅图中任意两点之间强连通则称这幅图为强连通图。有向图的极大强连通子图就是有向图的强连通分量(Strongly Conneted Component)。强连通有如下性质:(1)自反性:任意顶点v和自身是强连通的。(2)对称性:如果v和w是强连通的,那么w和v也是强连通的。(3)传递性:如果v和w是强连通的且...原创 2018-10-23 20:32:14 · 5044 阅读 · 1 评论 -
有向图及拓扑排序
有向图在无向图中,边没有方向,两条边之间的顶点是单向可达的,而有向图的边是单向的。虽然边的性质不同,但我们仍然可以用邻接表来表示有向图。对有向图的结构定义如下:#include <map>#include <forward_list> using namespace std; struct DirectedGraph{ size_t V, E;...原创 2018-10-20 23:06:53 · 16651 阅读 · 2 评论 -
图的连通分量寻找
连通分量无向图G的极大连通子图称为G的连通分量(Connected Component)。任何连通图(任意两个顶点之间可达的图)都只有一个连通分量,即自身,非连通图有多个连通分量。深度优先搜索的特点非常适合用于求解图的连通分量,每一次深度优先遍历所经过的顶点就是一个连通分量。因此只需要对图的每一个顶点调用一次深度优先遍历(注意标记访问过的顶点),就可以求得所有的连通分量。/* s...原创 2018-10-22 00:26:14 · 3447 阅读 · 0 评论 -
Dijkstra算法
Dijkstra算法是求解带权有向图中两点之间最短路径的经典算法,它采用贪心策略,维护一个向量dis用来表示从起点到其余顶点的路径“长度”。其主要原理如下:1.定义一个向量dis[],下标表示顶点,即dis[v]的值表示为从起点到v点的已知最短路径长度。初始化向量时,若v不是起点的相邻顶点,则dis[v]=∞,起点dis[0]=0。2.定义向量edge[],下标和值都表示顶点,假设edge...原创 2018-10-29 18:16:55 · 1523 阅读 · 0 评论 -
基数排序
基数排序(Radix Sort)属于分配式排序算法的一种,它是将待排序序列的元素切分为许多个部分作为排序键,对序列的每一趟排序都会更换不同的键(由低位到高位或是由高位到低位)进行计数排序。这种排序思想要求每一趟排序都是稳定的,即相同键值的相对位置不会发生改变,而计数排序可以满足这个要求。低位优先低位优先(Least Significant Digital,LSD)的基数排序主要应用于元素都...原创 2018-11-01 09:48:50 · 1806 阅读 · 0 评论 -
有向无环图的最短路径求解算法
对于最短路径问题,Dijkstra算法只能求解所有边的权值都是非负的加权有向图,而Bellman-Ford算法虽然可以求解有负权值边的图的最短路径,但效率并不高。对于有向无环图,下面这种基于Dijkstra和拓扑排序的算法可以在线性时间内解决单点最短路径问题,且能够处理负权重的边,甚至能够求出最长路径。该算法的思想很简单:按照拓扑顺序放松顶点。因为每条边v→w都只会被放松一次,当v被放松时有:...原创 2018-10-29 21:45:34 · 3797 阅读 · 0 评论 -
最小生成树及其求解算法
最小生成树图论中,树是图的一种特殊形式,它的众多性质中有两个是求解最小生成树的Prim算法和Kruskal算法的基础:(1)用一条边连接树中的任意两个顶点都会产生一个新的环;(2)从树中删去一条边将会得到两棵独立的树。无权图中的边只是单纯的作为联系两个顶点的抽象概念,而带权图(也称加权图)中为边增加了权重,使得顶点之间的路径形式变得更丰富多样。图的生成树是它的一棵含有其所有顶点的无...原创 2018-10-24 21:03:47 · 2076 阅读 · 0 评论 -
Bellman-Ford算法及其优化
与Dijkstra算法一样,我们定义一幅加权有向图的结构如下://带权有向图struct EdgeWeightedDigraph{ size_t V; //顶点数 size_t E; //边数 map<int, forward_list<tuple<int, int, double>> adj; //改进后的邻接表,tuple存储的是边集}Be...原创 2018-10-30 12:09:29 · 2212 阅读 · 0 评论 -
计数排序
在所有基于比较的排序算法中,最快的算法其时间复杂度为O(NlogN),事实上可以证明,这已经是基于比较的排序算法的时间复杂度下界了。但有一种实现简单的非比较排序算法可以突破基于比较的排序算法这一时间下界——计数排序(Counting Sort)。如果我们的待排序序列为整数且有一个已知的数值范围K,那么计数排序可以在O(N+K)的时间复杂度内将序列排序好。在多数情况下计数排序的效率比任何基于比较...原创 2018-10-30 22:03:35 · 194 阅读 · 0 评论 -
希尔排序
对于大规模乱序数据插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点地从数组的一端移动到另一端。希尔排序简单改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。希尔排序把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个序列恰好被分成一组。因此希尔排序也叫缩小增...原创 2018-10-13 17:39:12 · 342 阅读 · 0 评论 -
二叉树的前中后序遍历
本文源码示例是自己在LeetCode上做的相关题目而来。前序遍历 遍历思想:根节点→左子树→右子树递归版本/** * Definition for a binary tree node. * struct TreeNode * { * int val; * TreeNode *left; * TreeNode *rig...原创 2018-10-12 01:13:15 · 564 阅读 · 0 评论 -
Simple Selection Sort(简单选择排序)
算法思想 一个拥有若干元素的序列,重复遍历序列,将其中最大(或最小)的元素找出来,按顺序放到指定位置,再将次大(或次小)元素找出来放到指定位置,直到所有元素排完。实现步骤 以从小到大为例:1.遍历序列,找出最小元素2.将找出的最小元素与第一个元素互换位置3.从第二个元素开始遍历,重复步骤1和2源码C/C++void SimpleSe...原创 2017-09-29 17:03:06 · 412 阅读 · 0 评论 -
Merge Sort(归并排序)
归并排序是建立在归并操作(将若干(通常为两个)有序的序列合成为一个更大的有序序列)上的一种排序算法,是分治法的典型应用。算法思想 用分治法的思想,将已有序的子序列合并,得到完全有序的序列,即先使每个子序列有序,再使子序列段间有序。常见的归并排序将两个有序的子序列合成一个更大的序列,称为二路归并排序。实现步骤 以自顶向下的二路归并...原创 2017-10-04 00:35:57 · 1781 阅读 · 0 评论 -
Quick Sort(快速排序)
目录算法思想实现步骤源码C++实现递归版本C++非递归版本 Python实现Go实现时间复杂度性能特点稳定性算法思想 通过快速排序将要排序的数据分为独立的两部分,其中一部分的数据比另外一部分的数据都要小,然后再按照此方法对这两部分数据分别再进行快速排序,整个过程可以递归进行,以此达到整个序列都有序。快速排序和归并排序是互补的:归并排序...原创 2017-10-08 23:04:05 · 1286 阅读 · 0 评论 -
Binary Selection Sort(二元选择排序)
算法思想 二元选择排序是对简单选择排序的改进,简单选择排序对序列每一次遍历只找出一个元素,而二元选择排序在每一次遍历中都会找出序列两端的元素(最大和最小),两端同时向中间逼近。这样理论上遍历的次数就减少了一半,加快了排序速度。实现步骤 以从小到大排列为例:1.遍历序列,找出最小元素和最大元素2.将最小元素与无序部分第一个元素交换,最大元素与无...原创 2017-10-03 12:07:37 · 786 阅读 · 0 评论 -
并查集和Union-Find算法及其改进
并查集定义 并查集(Union-Find Sets)也叫不相交集合(Disjoint Sets),是一种用于维护若干个不相交元素所构成的集合的一种树型数据结构。并查集常用来处理一些不相交元素的合并与查询问题,在使用中常常用森林来表示。 主要操作 一个并查集数据结构维护了一个不相交动态集的集合。我们用一个代表(根节点)来标识每个集合,它是这个集合的某个成...原创 2017-10-19 16:53:13 · 961 阅读 · 0 评论 -
Heap Sort(堆排序)
堆排序(HeapSort)是利用堆结构(常用二叉堆)所设计的一种排序算法,属于选择排序的一种。关于堆结构的介绍参见另一篇博文:点击打开链接算法思想 堆排序利用堆结构根节点的元素最大(或最小)的特点,不断取出根节点并维护堆结构来实现排序。实现步骤 以大根堆为例:1.建堆,将初始序列建成一个大根堆 2.将根节点(首元素)与最后...原创 2017-11-05 13:48:08 · 8679 阅读 · 0 评论 -
Bubble Sort(冒泡排序)
算法思想 一个拥有若干元素的序列,重复遍历该序列,每一次遍历比较两个元素,将不符合指定排序规则的两元素交换,直到序列末端,则排序完成。该算法因为其排序的序列元素较大(或较小)者会在每次交换中慢慢浮到序列端部而得名冒泡排序。实现步骤 以从小到大的顺序为例:1.比较相邻的两个元素,如果第一个比第二个大则交换顺序2.从第一对元素比较到最后一对元素,这样最...原创 2017-09-29 16:05:18 · 1412 阅读 · 0 评论 -
欧几里得算法及其扩展
欧几里得算法欧几里得算法(Euclidean Algorithm)也叫辗转相除法,是数论中的一项基本技术,它通过一个简单的过程来确定两个正整数的最大公约数。欧几里得算法基于下面的定理:对任何非负整数a和b:gcd(a, b) = gcd(b, a mod b) (a ≥ b)可重复使用上式求出最大公约数。重复计算结束的条件是后一个整数等于0,此时前一个数即为二者的最大公约数。...原创 2018-04-13 11:01:53 · 491 阅读 · 0 评论 -
质数筛选算法:The Sieve of Eratosthenes
质数 质数(prime number)也叫素数,为大于1的且除1和本身以外不再有其他因数的自然数,与之相对的是合数。质数有无限个。 性质·质数只有两个因数:1和本身·任何大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的·质数的个数是无限多的·若n为正整数,在n²到(n+1)²之间至少有一个质数·若n为大于等于2的正整数,则n到n!之...原创 2018-05-27 16:08:40 · 8841 阅读 · 1 评论 -
快慢指针
快慢指针是指两个移动速度不同的指针,一个指针移动的步长大于另一个指针(多为2倍关系)。在链表中快慢指针有很多应用,例如判断是否存在环链、寻找链表中点等。判断环链及寻找环入口假设快指针的移动步长为2,慢指针的移动步长为1,两者同时从一个链表的起点出发向前移动,则当两个指针可以相遇时,该链表存在环链。原理很简单,从同一起点出发朝着相同方向(假设只有一条路径)的两个速度不同的物体,以慢的物体为参...原创 2018-06-04 23:44:15 · 949 阅读 · 0 评论 -
散列表
定义 散列表(Hash Table)也叫哈希表,是根据关键字进行数据访问的数据结构。散列表将关键字映射到表中的某个位置来访问数据,提供映射的叫散列函数(Hash Function)。通过散列函数,我们可以实现对数据的快速访问(理想情况下是常数时间内,但这取决于散列函数、碰撞概率、负载系数等因素)。 实际上,散列表是普通数组概念的推广。由于对普通数组可以直接寻址,使得...原创 2018-05-24 13:39:23 · 958 阅读 · 0 评论 -
二叉堆
堆结构定义 堆是一种树型结构,对于堆结构来说,堆的每一个节点的元素都要大于(或小于)其所有子节点的元素,满足这一条件的树被称为堆。若每个节点元素大于其所有子节点的元素,则这个堆被称为大根堆(最大堆),反之若每个节点元素小于其所有子节点的元素,则被称为小根堆(最小堆)。 二叉堆是每个节点最多只有两个子节点的堆,它可以被看成一个近似地完全二叉树,可以用数组表示。二叉堆除...原创 2017-11-04 16:57:46 · 873 阅读 · 0 评论 -
字符串匹配算法
目录Brute-Force算法Knuth-Morris-Pratt算法确定有限状态自动机部分匹配表Boyer-Moore算法Rabin-Karp算法总结网络信息中充满大量的字符串,对信息的搜寻至关重要,因此子字符串查找(即字符串匹配)是使用频率非常高的操作:给定一段长度为N的文本和长度为M的模式字符串(N≥M),在文本中找到一个和模式串相匹配的子串。由这个问题可以延...原创 2018-11-05 17:58:47 · 14979 阅读 · 1 评论