算法与数据结构(C++)
蓝子娃娃
越努力,越幸运!!!
展开
-
动态规划
收藏一下讲得比较好的动态规划博客,写得很好,方便自己观看动态规划原创 2020-09-20 16:09:11 · 85 阅读 · 0 评论 -
图论算法(二)
文章目录说在前面图的遍历1. 深度优先遍历2. 广度优先遍历说在前面在图论算法一中介绍了图的分类以及实现了邻接表与邻接矩阵的基本实现。下面我将介绍图的遍历算法。图的遍历回顾一下,之前树的遍历算法中,有深度优先遍历和广度优先遍历。所以我们先来介绍图的深度优先遍历。1. 深度优先遍历我将以下面这张图作为实例,演示图的深度优先遍历是怎么实现的。首先这是一张稀疏图,我们用邻接表来实现。所谓的深度优先遍历,首先得把握两个点。第一点就是深度优先,就是从一个点开始,不停的向下试,直到试不下去为止。这原创 2020-09-15 16:42:19 · 180 阅读 · 0 评论 -
图论算法(一)
文章目录图论(Graph Theory)图的分类图的相关概念1. 图的连通性2. 简单图(Simple Graph)图的表示1. 邻接矩阵2. 邻接表(Adjacency Lists)3. 使用场景邻接表和邻接矩阵的具体实现1. 定义以及添加边2. 遍历邻边 - 最常见的操作图论(Graph Theory)图,在我们的现实生活中,运用十分广泛。上面一张图,可以用在交通运输中,社交网络,互联网,工作安排,脑区活动,程序状态执行(自动机)等等。图的分类图可以分为 无向图(Undirected G原创 2020-09-15 09:50:27 · 1404 阅读 · 0 评论 -
平衡树和 AVL 树
文章目录AVL 树平衡二叉树AVL 树的左旋转和右旋转情况一(LL):插入的元素在不平衡节点的左侧的左侧(进行右旋转)情况二(RR):插入的元素在不平衡节点的右侧的右侧(进行左旋转)情况三(LR):插入的元素在不平衡节点的左侧的右侧情况四(RL):插入的元素在不平衡节点的右侧的左侧AVL 树最早的自平衡二分搜索树结构。平衡二叉树对于任意一个节点来说,左子树和右子树的高度差不能超过1。下面我们看一个例子。这棵树有可能看起来不是那么的平衡,但是它的确是平衡二叉树。但是这种树一般不会出现在堆和线段树原创 2020-09-09 21:23:13 · 160 阅读 · 0 评论 -
Trie 树
文章目录前言什么是 Trie?Trie 和 前缀搜索前言 trie 是专门为处理字符串而设计的。 假设一下,如果有 n 个条目,使用树结构,那么查询的时间复杂度为 O(logn)。如果有 100 万个条目,logn 大约有 20。但是如果我们使用 trie,它的查询的时间复杂度和字典中一共多少个条目无关。只与查询的字符串的长度相关,若要查询的字符串长度为 w,那么时间复杂度为 O(w)。这是非常有优势的,因为对于绝大多数的单词而言,长度一般小于 10。 下面,我们来看一下,trie 是怎么实现原创 2020-08-27 19:23:07 · 523 阅读 · 0 评论 -
并查集
文章目录并查集实现并查集的一种思路(quick find)1. 并查集的基本数据表示2. 并查集的功能实现并查集的另一种思路(Quick Union)实现2. 第一种和第二种性能比较并查集对于一组数据,主要支持两个动作:union(p, q):将 p 和 q 合并在一起find§:查看 p 在哪个组中用来回答一个问题isConnected(p, q):p 和 q 是否相连在一起实现并查集的一种思路(quick find)查找效率很高,但是执行变的过程却不尽人意。1. 并查集的基本数据表原创 2020-08-26 19:43:49 · 854 阅读 · 0 评论 -
详解 二叉搜索树
文章目录查找问题二分查找法(Binary Search)查找问题查找问题是计算机中非常重要的基础问题二分查找法(Binary Search)对于有序数列,才能使用二分查找法(排序的作用)比如我们查找一个数 X,那我们先找到整个数组中间的元素 V,如果元素 X 恰巧等于元素 V,那么我们就找到了元素 X。否则,元素 V 将整个数组分成两部分,小于 V 的部分和大于 V 的部分。如果 X 小于 V,就在小于 V 的部分继续查找;如果 X 大于 V,就在大于 V 的部分继续查找;时间复杂度为 O(log原创 2020-08-16 14:12:39 · 318 阅读 · 0 评论 -
动态规划相关算法题
动态规划(Dynamic Programming)动态规划简称 DP,其定义是动态规划是分治思想的延伸,通俗一点来讲就是大事化小,小事化无的艺术。在将大问题化解为小问题的分治过程中,保存对这些小问题已经处理好的结果,并供后面处理更大规模的问题时直接使用这些结果动态规划具备了以下三个特点:把原来的问题分解成了几个相似的子问题所有的子问题都只需要解决一次储存子问题的解动态规划的本质,是对问题状态的定义和状态转移方程的定义(状态以及状态之间的递推关系)动态规划问题一般从以下四个角度考原创 2020-08-02 18:23:19 · 217 阅读 · 0 评论 -
索引堆的优化
上一篇博客索引堆的构建中我们留下了一个问题,当我们想要修改堆中一个元素数据时,需要的时间复杂度为O(n)。那么这篇文章将对该算法进行一个优化,将其时间复杂度提升至O(logn)之前的change函数如下 //希望将索引为i的元素的值修改为 newItem void change(int i, Item newItem) { i += 1; data[i] = newItem; //要找到index[j原创 2020-07-19 19:11:35 · 90 阅读 · 0 评论 -
索引堆的构建
【注意】索引堆的实现是建立在堆排序的基础上,还不了解堆排序的柚子,可以参考我的这篇博客二叉堆(最大堆)之堆排序【代码实现】#include <iostream>#include <cassert>#include <algorithm>#include <ctime>#include <string>#include <cmath>#include <typeinfo>#include <cstri.原创 2020-07-19 18:27:48 · 88 阅读 · 0 评论 -
排序算法总结
这篇博客主要比较的是插入排序和三种时间复杂度为O(logn)级别的算法原创 2020-07-19 18:17:33 · 67 阅读 · 0 评论 -
堆排序之原地堆排序
之前介绍了堆排序,现在我们来聊聊原地堆排序【代码】//原地堆排序template<typename T>void heapSort3(T arr[], int n){ //将数组构建成一个堆 for(int i = (n - 1) / 2; i >= 0; i--) { __shiftDown(arr, n, i); } for(int i = n - 1; i > 0; i--) { swa原创 2020-07-18 21:49:59 · 1072 阅读 · 0 评论 -
数组的堆化过程(Heapify)
二叉堆(最大堆)之堆排序【代码】添加如下构造函数即可//只需要在之前的堆排序中添加一个这样的构造函数即可 MaxHeap(Item arr[], int n) { data = new Item[n + 1]; capacity = n; for(int i = 0; i < n; i++) { data[i + 1] = arr[i]; } count = n; //从第一个非叶子节点开始 f.原创 2020-07-18 21:46:21 · 3238 阅读 · 0 评论 -
二叉堆(最大堆)之堆排序
#include <iostream>#include <cassert>#include <algorithm>#include <ctime>#include <string>#include <cmath>#include <typeinfo>#include <cstring>using namespace std;template<typename Item>cla.原创 2020-07-18 21:33:31 · 216 阅读 · 0 评论 -
快速排序的衍生问题之求数组中第n大元素
快速排序求数组中第n大元素还不了解快速排序的柚子,请参考我的这篇博客聊聊时间复杂度为O(nlogn)的快速排序(下) //快速排序求数组中第n大的元素 // 寻找arr数组中第k小的元素, k从1开始索引, 即最小元素是第1小元素, 以此类推 template<typename T> T findN(T arr[], int n, int key) { return __findN(ar原创 2020-07-17 20:08:30 · 220 阅读 · 0 评论 -
归并排序的衍生问题之求数组中逆序对的数量
求数组中逆序对的数量是建立在归并排序算法基础上的衍生问题还不是很懂归并排序算法的朋友,可以参考我的这篇博客聊聊时间复杂度为O(nlogn)的归并排序(上) //利用merge思想求逆序对的个数 // 递归求arr的逆序数对个数 template<typename T> long long inversionCount(T arr[], int n) { return __invers原创 2020-07-17 17:18:20 · 173 阅读 · 0 评论 -
快速排序之三路快速排序
之前介绍了快速排序和优化版的快速排序下面再来介绍一种 【三路快速排序】【代码实现】//三路快速排序 template<typename T> static void quickSort3Ways(T arr[], int n) { __quickSort3Ways(arr, 0, n-1); } template<typename T> static void原创 2020-07-15 18:13:57 · 259 阅读 · 0 评论 -
聊聊时间复杂度为O(nlogn)的快速排序(下)
上一篇博客中,我介绍了快速排序的第一版本的写法,但是我用一个拥有1000000个元素的几乎有序的数组测试了快速排序和归并排序,发现快速排序效率远远低于归并排序,这不是我们能够接受的。下面我将对快速排序进行优化~~【了解了原理,让我们来实现代码吧】 //快速排序优化 template<typename T> static void quickSort2(T arr[], int n) { __quickSort2原创 2020-07-15 18:08:58 · 274 阅读 · 0 评论 -
聊聊时间复杂度为O(nlogn)的快速排序(上)
快速排序快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影。快速排序原理图了解了原理,让我们直接上代码吧//快速排序 template<typename T> void quickSort(T arr[], int n) {原创 2020-07-14 17:10:22 · 198 阅读 · 0 评论 -
聊聊时间复杂度为O(nlogn)的归并排序(下)
自底向上的归并排序上一节介绍了使用递归的自顶向下的归并排序,这节我们聊聊能不能不适用递归实现归并排序【上原理图】【下面开始设计算法】算法设计完成,让我们直接敲代码吧 //实现归并 template<typename T> void __merge(T arr[], int l, int m, int r) { //先创建一个等大的临时空间 T temp[r - l + 1]; //将归并数组[l, r]复制到临时数组中 f原创 2020-07-14 15:06:44 · 353 阅读 · 0 评论 -
聊聊时间复杂度为O(nlogn)的归并排序(上)
归并排序(Merge Sort)概念归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。归并归并操作,也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。归并排序图解【思考】为什么要把一个数组先分成一半,然后再进行归并呢?对于我们的例子,有8个元素,一共可以分成3级,到第3级的时候,每一部分只剩下原创 2020-07-13 18:40:19 · 298 阅读 · 0 评论 -
聊聊时间复杂度为O(n^2)的排序算法
O(n^2)方的排序算法1. 选择排序(Selection Sort)图解选择排序代码这里使用模板,可以通过模板来对任何数据类型的数组或自定义类进行排序template<typename T>void selectionSort(T arr[], int n){ for(int i = 0; i < n; i++) { //寻找[i, n)区间中最小元素 int minIndex = i; for(int j = i + 1; j < n; j++原创 2020-07-12 20:30:27 · 730 阅读 · 0 评论