
数据结构与算法
文章平均质量分 56
想要走的更扎实,走的更远,必须深入底层,学习算法。
༄༊心灵骇客༣
路漫漫其修远兮,吾将上下而求索。
展开
-
排序算法的稳定性
排序算法的稳定性稳定性排序算法总结稳定性稳定性是指同样大小的样本再排序之后不会改变相对次序。对于基础类型来说,稳定性毫无意义。对于非基础类型来说,稳定性有重要意义。有些排序算法可以实现成稳定的,而有些排序算法无论如何都实现不成稳定的。排序算法总结...原创 2022-03-30 13:21:13 · 463 阅读 · 0 评论 -
红黑树 —— 个人解读
红黑树前言2-3树红黑树前言时隔半年多,再次解读红黑树,之前的文章对红黑树(Red Black Tree)进行了只是对红黑树的性质直接进行了说明,但并没有分析红黑树到底是怎么产生的,红和黑又是如何组成的。在《算法导论》一书中对红黑树的性质进行了深奥解读,对于初学者来说非常不友好,对于我自己来说也只是记得性质,应该是这样,而不知其所以然。A red-black tree is a binary tree that satisfies the following red-black properties原创 2022-02-17 20:11:04 · 552 阅读 · 0 评论 -
AVL树 —— 个人解读
AVL树平衡二叉树二级目录三级目录平衡二叉树对于任意一个节点,左子树和右子树的高度差不能为超过1平衡二叉树的高度和节点数量,之间的关系也是O(logn)的二级目录三级目录原创 2021-11-12 23:05:15 · 933 阅读 · 0 评论 -
并查集 —— 个人解读
并查集什么是并查集Quick Find(第一版并查集)Quick Union什么是并查集并查集(Union Find)是一种用于管理分组的数据结构。对于一组数据,主要支持两个动作:union(p,q)isConnected(p,q)对于并查集,我们设计一个interfaceUF来看两个元素是否所属一个集合(是否连接的),以及合并两个元素。public interface UF { int getSize(); boolean isConnected(int p, int原创 2021-11-10 21:42:42 · 605 阅读 · 0 评论 -
Trie字典树 —— 个人解读
Trie字典树什么是TrieTrie字典树的添加Trie字典树的查询Trie字典树的前缀搜索Trie字典树和简单的模式匹配什么是Trie每个节点有若干指向下个节点的指针。 class Node { Map<char, Node> next; }Trie字典树的添加package Trie字典树;import java.util.TreeMap;/** * 描述 Trie字典树 * * @author lixinzhen原创 2021-11-09 20:35:23 · 144 阅读 · 0 评论 -
线段树 —— 个人解读
线段树经典问题(区间染色和区间查询)创建线段树线段树中的区间查询线段树中的更新操作经典问题(区间染色和区间查询)有一面墙,长度为n,每次选择一段儿墙进行染色,m次操作后 ,我们可以看见多少中颜色?m次操作后,我们可以在[i,j]区间内看见多少中颜色?对此我们可以使用数组和线段树实现:操作使用数组实现使用线段树实现更新O(n)O(logn)查询O(n)O(logn)对于给定区间:更新:更新区间中一个元素或者一个区间的值查询:查询一个区间[i,j]的最大原创 2021-11-02 08:06:40 · 135 阅读 · 0 评论 -
希尔排序法 —— 个人解读
希尔排序基本思想实现希尔排序基本思想让数组越来越有序,可以处理不相邻的逆序对。基本原理:对于元素间距为n/2的所有数组做插入排序对元素间距为n/4的所有数组做插入排序对元素间距为n/8的所有数组做插入排序…对元素间距为1的所有数组做插入排序如下图中,相同颜色的两个元素为一组,且之间的索引差都为4。在每一组中进行插入排序,如1和2这一组经过插入排序后变成如下:其它三组元素也是这样,完成一次希尔排序后变成如下这样:希尔排序的下一步就是将整个数组距离为2进行分组。为啥是2,之前是原创 2021-11-01 18:57:56 · 121 阅读 · 0 评论 -
堆和优先队列 —— 个人解读
优先队列什么是优先队列堆的基本结构用数组存储二叉堆(最大堆)什么是优先队列普通队列:先进先出,后进后出优先队列:出队顺序和入队顺序无关;和优先级相关堆的基本结构采用堆作为优先队列的底层是一种高效的实现,因为堆作为底层,时间复杂度入队和出队都是O(logn)级别。二叉堆的性质:堆中某个节点的值总是不大于其父节点的值一个(最大)二叉堆是一个具有最大堆特性的完全二叉树。二叉堆是可用于实现高效优先队列ADT的数据结构之一。在优先队中,每一个元素都有一个优先级并且一个高优先级的元素总是比低优原创 2021-10-26 22:46:32 · 189 阅读 · 0 评论 -
二分搜索树 —— 个人解读
二分搜索树二分搜索树的特性二分搜索树添加元素二分搜索树的查询操作二分搜索树的遍历二分搜索树的特性二分搜索树的每个节点的值:大于其左子树的所有节点的值小于其右子树的所有节点的值二分搜索树存储的元素必须具有可比较性。二分搜索树添加元素因为整体代码较长,只给出部分核心代码,下文同样如此。采用递归算法插入元素 //向二分搜索树添加新的元素e public void add(E e) { root = add(root,e); } //向以node为根的原创 2021-10-22 22:22:35 · 118 阅读 · 0 评论 -
二分查找法 —— 个人解读
二分查找法对于有序数列,才能使用二分查找法,二分查找法的时间复杂度是O(log n)package 二分查找法;/** * 描述 二分查找法 * 对于有序数列,才能使用二分查找法,二分查找法的时间复杂度是O(log n) * * @author lixinzhen * @create 2021/10/21 11:19 */public class BinarySearch { private BinarySearch(){} /** * 非递归实现二原创 2021-10-22 20:50:36 · 107 阅读 · 0 评论 -
快速排序法 —— 个人解读
快速排序法快速排序法的原理Partition第一版快速排序法快速排序法的原理每次从当前考虑的数组中选择一个元素,以这个元素为基点,之后将这个元素挪到排好序的时候应该所在的位置。这样就有一个性质,这个元素之前的所有元素小于它,之后的所有元素大于它。然后分别对这两边进行快速排序,逐渐递归下去,完成整个排序过程。Partition更加抽象的说,对于数组的一个区间,如果我们选定了一个标定点v,如何把v放到正确的位置,使得v前面的元素都是小于它,v后面的元素都是大于它。那么这样的一个过程被称为partiti原创 2021-09-30 17:55:39 · 1042 阅读 · 0 评论 -
归并排序法 —— 个人解读
归并排序:将一个大的数组拆分成两个小数组,对着两个小数组进行处理完成后进行合并,并对大数组进行扫描一遍,当处理小数组的时候又会将小数组分成更小的两个数组,并对其进行处理,后归并扫描一遍小数组,依次类推直至找到最小再合并。归并排序原理:是递归算法中的一个典型的分治法策略。将原问题分解成两个子问题,如果将这两个子问题的解合并起来就完成了对原问题的解,这样的一种模式就是分治算法。具体过程笔者花了个图,如下:上图展示的是一个递归树,形象的展示出了递归算法的整个调用过程。从递归树中可以看出一共有logn层,每原创 2021-09-29 12:01:29 · 150 阅读 · 0 评论 -
选择排序和插入排序 —— 个人解读
选择排序和插入排序选择排序插入排序选择排序总是把还没处理的最小的那个元素拿出来(从小到大),可以进行原地排序public class SelectionSort { private SelectionSort() { } public static <E extends Comparable<E>> void sort(E[] arr) { //arr[0..i)是有序的,arr[i..n)是无序的 for (int原创 2021-09-28 16:55:04 · 134 阅读 · 0 评论 -
线性查找法 —— 个人解读
线性查找法:从数组起始位置依次比较判断是否包含需要的目标对象,若找到直接返回下标。核心算法:public static <E> int search(E[] data, E target) { for (int i = 0; i < data.length; i++) if (data[i].equals(target))//对象比较用equals return i; return -1;原创 2021-08-12 01:13:51 · 121 阅读 · 0 评论 -
数据和索引之间的联系
我们都知道innodb在进行数据插入的时候,必须要将数据跟某一个索引绑定在一起,这个索引可以是主键,如果没有主键,会选择唯一键,如果没有唯一键,会选择一个6字节的rowid来进行存储,无论如何,数据一定跟某一个索引列放在一起。那么一个表中可以有多少个索引?每个索引是否是一棵独立的B+树?答案是可以不止一个索引,且每个索引都是一棵B+树,都存储在.ibd的文件中。当我有多个索引的时候,数据也要存储多份吗?当然不需要,数据只会存储一份。相信大家都知道聚簇索引的数据跟索引是存储在一起的,非聚簇索引数据跟原创 2021-06-04 01:55:10 · 431 阅读 · 0 评论 -
冒泡排序算法
冒泡排序如果有n个数据进行排序,总共需要比较n-1次每一次比较完毕,下一次的比较就会少一个数据参与/* * 冒泡排序: * 一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面, * 依次对所有的数据进行操作,直至所有数据按要求完成排序 * */public class ArraysDemo { public static void main(String[] args) { int[] arr原创 2021-07-12 12:43:43 · 99 阅读 · 0 评论 -
优化后的十大排序算法(java)
优化后的十大排序算法冒泡排序选择排序插入排序希尔排序归并排序快速排序堆排序计数排序桶排序基数排序冒泡排序选择排序冒泡排序选择排序插入排序希尔排序归并排序快速排序堆排序计数排序桶排序基数排序冒泡排序如果序列尾部已经局部有序,可以记录最后1次交换的位置,减少比较次数public class BubbleSort { public static void main(String[] args) { int[] array = {2, 3, 1, 5, 8, 4};原创 2021-06-28 01:59:19 · 157 阅读 · 0 评论 -
红黑树(Red Black Tree)
红黑树是一种自平衡的二叉搜索树,以前叫做平衡二叉B树(Symmetric Binary B-tree)红黑树必须满足以下5条性质结点是RED或者BLACK根结点是BLACK叶子结点(外部结点,空结点)都是BLACKRED结点的子结点都是BLACK,RED结点的parent都是BLACK从根结点到叶子结点的所有路径上不能有2个连续的RED结点从任一结点到叶子结点(null结点)的所有路径都包含相同数目的BLACK结点如图是我通过Visualizations进行插入数据得到的红黑树。红原创 2021-07-02 23:50:48 · 218 阅读 · 2 评论 -
AVL树(LL,RR,LR,RL)
AVL树是最早发明的自平衡二叉搜索树之一。平衡因子(Balance Factor):某结点的左右子树的高度差AVL树的特点每个结点的平衡因子只可能是1,0,-1(绝对值<=1,如果超过,称之为“失衡”)每个结点的左右子树高度差不超过1搜索,添加,删除的时间复杂度是O(logn)添加导致的失衡最坏情况:可能会导致所有祖先结点都失衡,父节点,非祖先结点,都不可能失衡。如何解决添加导致的失衡?旋转有LL-右旋转(单旋) RR-左旋转(单旋) LR-RR左旋转,LL右旋转(双旋) RL-原创 2021-06-27 20:59:36 · 939 阅读 · 2 评论 -
二叉树基本概念
前言:前文讲了动态数组(ArrayList)及LinkedList(链表部分)底层实现,本来想写关于Stack,Deque相关源码,自己在看源码设计源码时写着写着发现这两者都可以用ArrayList或者LinkedList实现,并且源码很简单,因此没有必要写出来,这里列出二叉树相关概念,引出AVL树和红黑树。二叉树(binary tree)的特点每个结点的度最大为2(最多拥有2棵子树)左子树和右子树是有顺序的即使某结点只有一棵子树,也要区分左右子树二叉树是有有序树还是无序树?有序树原创 2021-06-27 03:39:11 · 185 阅读 · 0 评论 -
从设计源码入手分析LinkedList
前言:写这个博客累的我要死,加上自己写源码看源码花了6个小时,可谓是幸苦至极。太累了太累了!!!链表(Linked List)是一种链式存储的线性表,所有元素的内存地址不一定是连续的。动态数组有个明显的缺点------>可能浪费大量存储空间,而链表能够做到用到多少就申请多少内存。这里我通过设计源码,以单链表为例,然后扩展为双链表,再扩展为循环双链表,循序渐进,分析LinkedList的本质,大家和我一起来往下分析吧。(注意:官方LinkedList源码是非循环的)官方设定了一个List接口继承原创 2021-06-23 15:58:17 · 139 阅读 · 0 评论 -
从设计源码入手分析动态数组
数组(Array)数组是一种顺序存储的线性表,所有元素的内存地址是连续的。int[] array = new int[]{11, 22, 33};当创建完这个数组的时候,堆空间只能放3个元素,以后想再放更多的元素是不可能的。在很多编程语言中,数组都有个致命的缺点,无法动态修改容量。但在实际开发中,我们希望数组的容量是可以改变的那么如何实现动态数组呢?我们可以自己设计动态数组,首先类名为ArrayList(注意,这不是java官方的ArrayList,但是这种源码设计和官方差不多,而且更简原创 2021-06-12 03:26:02 · 1442 阅读 · 3 评论 -
如何评价一个算法的好坏?
如何评价一个算法的好坏?如果单从执行效率上进行评估,可能会想到这么一种方案比较不同算法对同一组输入的执行处理时间这种方案也叫做:事后统计法下面例举斐波那契数列的例子我们知道类似于 0 1 1 2 3 5 8…这样的数列叫斐波那契数列,对于如何求斐波那契数列中的某一个值,大家普遍的做法是采用递归,即F(n)=F(n-1)+F(n+1);如下public static int fib1(int n) { //n<=1,第一个数和第二个数都是本身 if (n原创 2021-06-10 03:40:31 · 2388 阅读 · 0 评论