![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
何事忧愁
何事忧愁?
展开
-
数据结构-B+树
前言B+树是对B树的一种变形树,它与B树的差异在于:1、非叶结点仅具有索引作用,也就是说,非叶子结点只存储key,不存储value。2、树的所有叶结点构成一个有序链表,可以按照key排序的遍历全部数据。B+树的优点:1、由于B+树在非叶子结点上不包含真正的数据,只当做索引使用,因此在内存相同的情况下,能够存放更多的key。2、B+树的叶子结点都是相连的,因此对整棵树的遍历只需要一次性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递原创 2021-09-29 21:58:50 · 505 阅读 · 0 评论 -
数据结构-B树
B树简介B树中允许一个结点中包含多个key,可以是3个、4个、5个甚至更多,并不确定。需要看具体的实现。现在我们选择一个参数M,来构造一个B树,我们可以把它称作是M阶的B树。M阶的B树的特点:1、每个结点最多有M-1个key,并且以升序排列2、每个结点最多能有M个子结点;3、根结点至少有两个子结点。在实际应用中B树的阶数一般比较大(通常大于100),所以,即使存储大量的数据,B树的高度仍然比较小,这样在某些应用场景下,就可以体现出它的优势。...原创 2021-09-29 21:49:24 · 93 阅读 · 0 评论 -
红黑树实现
前言红黑树的基本思想是用标准的二叉查找树和一些额外的信息(替换3-结点)来表示2-3树。树中的链接分为两种类型:红链接:将两个2-结点连接起来构成一个3-结点。黑链接:则是2-3树中的普通链接。红黑树的定义红黑树是含有红黑链接并满足下列条件的二叉查找树:1、红链接均为左链接2、没有任何一个结点同时和两条红链接相连3、该树是完美黑色平衡的,即任意空链接到根结点的路径上的黑链接数量相同。平衡化左旋当某个结点的左子结点为黑色,右子结点为红色,此时需要左旋。前提.原创 2021-09-29 00:27:50 · 67 阅读 · 0 评论 -
索引队列-索引优先队列
实现思想1、存储数据时,给每一个数据元素关联一个整数,例如insert(int k, T t),我们可以看做 k 是t的关联的整数,那么我们的实现需要通过k这个值,快速获取到队列中 t 这个元素,此时有个k这个值需要具有唯一性。2、通过第一步后,得到的数组items并不是堆有序,所以,我们增加一个数组 int[] auxiliary ,保存每个元素在items数组中的索引,auxiliary数组需要堆有序。3、增加一个数组int[] reverse,用来存储auxiliary 的逆序,所谓逆序.原创 2021-09-28 01:36:43 · 359 阅读 · 0 评论 -
优先队列-最小优先队列
前言1.最小的二元素放在数组的索引1处。2.每个结点的数据总是小于等于它的两个子结点的数据。public class MinPriorityQueue<T extends Comparable> { T[] items; int size; public MinPriorityQueue(int capacity) { items = (T[]) new Comparable[capacity+1]; size =0原创 2021-09-27 22:34:36 · 166 阅读 · 0 评论 -
优先队列-最大优先队列
前言可以获取并删除队列中最大的值public class MaxPriorityQueue<T extends Comparable> { T[] items; int size; public MaxPriorityQueue(int capacity) { items = (T[]) new Comparable[capacity+1]; size =0; } //判断堆中索引i处的元素是否小于索引j处原创 2021-09-27 22:23:59 · 44 阅读 · 0 评论 -
树结构-堆排序
前言给定一个数组:String[] arr = {"S","O","H","G","B","C","E","F","M","L","A","D","L"}请对数组进行排序实现思路1、构造堆2、得到堆顶元素,这个值就是最大值3、交换堆顶元素和数组中最后一个元素,此时所有元素中的最大元素已经放到合适的位置4、对堆进行调整,重新让出了最后一个元素的剩余元素中的最大值放到堆顶。5、重复2-4步骤,直到剩下一个元素为止。代码实现public class HeapSort原创 2021-09-27 01:26:33 · 67 阅读 · 0 评论 -
树结构-堆的实现
前言1、堆是完全二叉树,除了树的最后一层结点不需要是满的,其他的每一层从左到右都是满的,如果最后一层不是满的,则要求左满右不满。2、如果一个结点的位置为k,则它的父节点的位置为k/2,而它的两个子结点的位置则分别为2k和2k+1。3、每个结点都大于它的两个子结点。而两个子结点的大小顺序并没有做规定。代码示例public class Heap<T extends Comparable> { T[] items ; int size; pub原创 2021-09-27 00:08:17 · 110 阅读 · 0 评论 -
二叉树-解决折纸问题
前言请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时折痕是凹下去的,即折痕突起的方向指向纸条的背面。 如果从纸条的下边向上方连续对折2次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。给定一个输入参数N,代表纸条都从下边向上方连续对折N次。 请从上到下打印所有折痕的方向。例如:N=1时,打印: down N=2时,打印: down down up代码实现public class App { public static原创 2021-09-26 22:45:13 · 126 阅读 · 0 评论 -
二叉树-获取树的深度
代码示例代码中用到的二叉树BinaryTree类是树结构-二叉查找树_lujiangui的专栏-CSDN博客这里自定义的二叉树类用的Queue类是线性表-队列_lujiangui的专栏-CSDN博客里的自定义队列类 //获取树的深度 public int getDept(){ return getDept(root); } //获取指定树的深度 public int getDept(Node x){ if (...原创 2021-09-26 22:45:01 · 107 阅读 · 0 评论 -
二叉树-层序遍历
前言层序遍历:从根结点(第一层)开始,一次向下,从左往右 获取每一层所有结点的值。代码示例代码中用到的二叉树BinaryTree类是树结构-二叉查找树_lujiangui的专栏-CSDN博客这里自定义的二叉树类用的Queue类是线性表-队列_lujiangui的专栏-CSDN博客里的自定义队列类 public Queue<K> levelTraversal(){ Queue<K> keys = new Queue<>...原创 2021-09-26 22:44:44 · 39 阅读 · 0 评论 -
二叉树-后序遍历
前言前序遍历:先访问左子树,再访问右子树,最后访问根结点代码示例代码中用到的二叉树BinaryTree类是树结构-二叉查找树_lujiangui的专栏-CSDN博客这里自定义的二叉树类用的Queue类是线性表-队列_lujiangui的专栏-CSDN博客里的自定义队列类 public Queue<K> postorderTraversal(){ Queue<K> keys = new Queue<>(); ...原创 2021-09-26 22:44:28 · 52 阅读 · 0 评论 -
二叉树-中序遍历
前言前序遍历:先访问左子树,再访问根结点,最后访问右子树代码示例代码中用到的二叉树BinaryTree类是树结构-二叉查找树_lujiangui的专栏-CSDN博客这里自定义的二叉树类用的Queue类是线性表-队列_lujiangui的专栏-CSDN博客里的自定义队列类 public Queue<K> mediumTraversal(){ Queue<K> keys = new Queue<>(); ...原创 2021-09-25 23:02:50 · 60 阅读 · 0 评论 -
二叉树-前序遍历
前言前序遍历:先访问根结点,再访问左子树,最后访问右子树代码示例代码中用到的二叉树BinaryTree类是树结构-二叉查找树_lujiangui的专栏-CSDN博客这里自定义的二叉树类用的Queue类是线性表-队列_lujiangui的专栏-CSDN博客里的自定义队列类 //按照前序遍历规则,从树中查找所有的key public Queue<K> preorderTraversal(){ Queue<K> keys...原创 2021-09-25 22:56:55 · 67 阅读 · 0 评论 -
树结构-二叉树查找最小值和最大值
前言此文章承接上一篇博文:树结构-二叉查找树_lujiangui的专栏-CSDN博客代码示例 //查找树中最小的键 public K getMin(){ return getMin(root).key; } //从指定的树中查找出最小的键的结点 public Node<K,V> getMin(Node x){ if (x==null){ return null; }原创 2021-09-25 22:19:38 · 1122 阅读 · 0 评论 -
树结构-二叉查找树
前言1.二叉树,即任意一个结点下面不能有超过两个子节点2.二叉查找树的特点为,左子结点小于父结点,父结点小于右子结点代码实现public class BinaryTree<K extends Comparable,V> { //根结点 private Node<K,V> root; private int size; public BinaryTree() { root = null; siz原创 2021-09-25 22:03:55 · 222 阅读 · 0 评论 -
符号表-有序的符号表
前言假如我们希望符号表能按照key排序,那么我们需要让key继承Comparable接口,修改put方法即可代码示例public class SymbolTable<K extends Comparable,V> { private Node<K,V> head; private int size; public SymbolTable() { head = new Node<>(null,null,null);原创 2021-09-25 13:19:10 · 171 阅读 · 0 评论 -
符号表-自定义符号表
前言符号表最主要的目的就是将一个键和一个值联系起来,符号表能够将存储的数据元素是一个键和一个值共同组成的键值对数据,可以根据键来查找相应的值。符号表中健要求唯一性。代码实现public class SymbolTable<K,V> { private Node<K,V> head; private int size; public SymbolTable() { head = new Node<>(null,原创 2021-09-25 12:43:38 · 116 阅读 · 0 评论 -
线性表-队列
前言队列是一种基于先进先出的数据结构,是一种只能在一端进行插入,在另一端进行删除操作的特殊线性表。代码示例public class Queue<T> implements Iterable<T>{ private Node<T> head; private Node<T> last; private int size; public Queue() { head = new Node<原创 2021-09-25 11:54:42 · 111 阅读 · 0 评论 -
栈-逆波兰表达式求值问题
前言逆波兰表达式又叫做后缀表达式,要搞清楚什么是后缀表达式,需要先了解一下什么是中缀表达式。1.中缀表达式中缀表达式就是我们生活中使用的表达式,例如:1+5*2等,中缀表达式的特点是:二元运算符总是置于两个运算量中间。2.逆波兰表达式逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasiewicz)于1929年首先提出的一种表达式的表示方法[1]。后来,人们就把用这种表示法写出的表达式称作“逆波兰表达式”。逆波兰表达式把运算量写在前面,把算符写在后面。问题给定...原创 2021-09-25 10:44:46 · 59 阅读 · 0 评论 -
栈-案例(括号匹配问题)
问题描述给定一个字符串,里边可能包含“()”小括号和其他字符,请编写程序检查该字符串中的小括号是否成对出现。该问题可以用栈来解决代码示例public class App { public static void main(String[] args) { String str = "我(爱你((中国))"; boolean ismatch = ismatch(str); System.out.println(ismatch);原创 2021-09-25 00:43:00 · 98 阅读 · 0 评论 -
线性表-栈及遍历
前言栈是一种基于先进后出的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出出书数据进入到栈的动作称为压栈,数据从栈中出来的动作称为弹栈(或出栈)代码实现public class Stack<T> implements Iterable<T>{ Node<T> head; int size; public Stack原创 2021-09-25 00:15:45 · 204 阅读 · 0 评论 -
约瑟夫问题
问题描述:据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直原创 2021-09-24 23:43:28 · 55 阅读 · 0 评论 -
线性表-双向链表
前言双向链表也叫双向表,是链表的一种,它由多个结点组成,每个结点都由一个数据域和两个指针域组成,数据域用来存储数据,其中一个指针域用来指向其后继结点,另一个指针域用来指向前驱结点。链表的头结点的数据域不存储数据,指向前驱结点的指针域值为null,指向后继结点的指针域指向第一个真正存储数据的结点。代码示例public class App { public static void main(String[] args) { BidirectionalLinkedList原创 2021-09-24 22:40:21 · 53 阅读 · 0 评论 -
线性表-单向链表及遍历
简介单向链表是链表的一种,它由多个结点组成,每个结点都由一个数据域和一个指针域组成,数据域用来存储数据,指针域用来指向其后继结点。链表的头结点的数据域不存储数据,指针域指向第一个真正存储数据的结点。public class App { public static void main(String[] args) { LinkList<String> list = new LinkList<>(); list.insert("aaa原创 2021-09-24 00:18:05 · 234 阅读 · 0 评论 -
线性表-顺序表动态扩容
public class App { public static void main( String[] args ){ //扩容 SequenceList<String> list = new SequenceList<>(3); System.out.println(list.capacity()); list.insert("aaa"); list.insert("bbb"); .原创 2021-09-22 23:48:44 · 228 阅读 · 0 评论 -
线性表-顺序表遍历
public class App { public static void main( String[] args ){ SequenceList<String> list = new SequenceList<>(10); list.insert("aaa"); list.insert("bbb"); list.insert("ccc"); list.insert("ddd"); .原创 2021-09-22 23:21:07 · 554 阅读 · 0 评论 -
线性表-顺序表
public class App { public static void main( String[] args ){ SequenceList<String> list = new SequenceList<>(10); list.insert("aaa"); list.insert("bbb"); list.insert("ccc"); list.insert("ddd"); .原创 2021-09-22 23:07:49 · 45 阅读 · 0 评论 -
排序算法之快速排序
排序原理1、首先设定一个分界值,通过该分界值将数组分成左右两部分2、将大于或等于分界值的数据放到数组右边,小于分界值的数据放到数组的左边。此时左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。3、然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。4、重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归拍好右侧两个部分的数据原创 2021-09-21 18:42:53 · 89 阅读 · 0 评论 -
排序算法之归并排序
排序原理1、尽可能的一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元素个数是1为止。2、将相邻的两个子组进行合并成一个有序的大组。3、不断的重复步骤2,直到最终只有一个组为止。public class App { static int[] temp ; public static void main( String[] args ){ int[] arr = {12,3,5,7,3,22,44,11,23,17,15,原创 2021-09-18 00:21:59 · 66 阅读 · 0 评论 -
排序算法之希尔排序
排序原理1、选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组。2、对分好组的每一组数据完成插入排序。3、减小增长量,最小减为1,重复第二步操作。增长量h的确定:增长量h的值每一固定的规则,采用以下规则:int h =1;while(h<数组的长度/2){ h = 2h +1;}//循环结束后就可以确定h的最大值//h的减小规则为:h =h/2代码示例public static void main(String[] args) {原创 2021-09-17 22:25:39 · 77 阅读 · 0 评论 -
排序算法之插入排序
排序原理1、把所有的元素分为两组,已经排序的和未排序的2、找到未排序的组中第一个元素,向已经排序的组中进行插入3、倒序遍历已经排序的元素,一次和带插入的元素进行比较,知道找到一个元素小于等于待插入元素,那么就把待插入元素放到这个位置,其他的元素向后移动一位。代码示例 public static void main(String[] args) { int[] arr = {2,5,4,6,11,32,3,8}; for (int i=1;i<arr.length;i+原创 2021-09-17 00:50:36 · 46 阅读 · 0 评论 -
排序算法之选择排序
排序原理1、每一次遍历的过程中,都假定第一个索引出的元素是最小值,和其他索引处的元素一次进行比较,如果当前索引的值大于其他某个索引处的值,则假定其他某个索引处的值为最小值,最后可以找到最小值所在索引。2、狡猾第一个索引处元素和最小值所在的索引处元素。代码示例 public static void main(String[] args) { int[] arr = {2,5,4,6,11,32,3,8}; for (int i=0;i<=arr.length-2;i++){原创 2021-09-17 00:38:31 · 39 阅读 · 0 评论 -
排序算法之冒泡排序
原理从第一个位置开始,依次进行相邻元素的比较。对每一对元素做同样的工作,从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值代码实战public static void main(String[] args){ //对该数组进行升序排序 Integer arr = {4,3,6,7,8,2,5}; for(int i=arr.length-1;i>0;i--){ for(int j=0;j<i;j++){原创 2021-09-17 00:13:06 · 41 阅读 · 0 评论 -
单链表面试题(新浪、百度、腾讯)
求单链表中有效节点的个数 //方法:获取到单链表的节点的个数(如果是带头结点的链表,需求不统计头节点) /** * * @param head 链表的头节点 * @return 返回的就是有效节点的个数 */ public static int getLength(HeroNode head) { if(head.next == null) { //空链表 return 0; } .原创 2020-07-25 23:11:26 · 149 阅读 · 1 评论 -
单链表
链表(Linked List)介绍链表是有序的列表,但是它在内存中是存储如下链表是以节点的方式来存储, 是链式存储每个节点包含 data 域, next 域:指向下一个节点.如图:发现 链表的各个节点不一定是连续存储.链表分 带头节点的链表和 没有头节点的链表,根据实际的需求来确定单链表(带头结点) 逻辑结构示意图如下单链表的应用实例使用带 head 头的单向链表实现 –水浒英雄排行榜管理完成对英雄人物的增删改查操作第一种方法在添加英雄时,直接添加到链表的尾部第二种原创 2020-07-25 22:22:26 · 62 阅读 · 0 评论 -
队列
队列介绍队列是一个有序列表,可以用数组或链表来实现。遵循先入先出的原则。数组模拟队列队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的最大容量就是数组的长度。因为队列的输出、输入是分别从前后端来处理,因此需要两个变量front及rear分别记录队列前后端的下表,front会随着数据输出而改变,rear则是随着数据输入而改变。当我们将数据存入队列时称为“addQueue”,addQueue的处理需要有两个步骤:将尾指针往后移:rear+1,当front==rear 【空】原创 2020-07-25 21:37:26 · 78 阅读 · 0 评论 -
稀疏数组概念及应用实例
稀疏数组稀疏数组的处理方法应用实例二维数组转稀疏数组的实现思路稀疏数组转原始数组的实现思路代码实现原始数组转稀疏数组稀疏数组转原始数组当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来存储给数组。稀疏数组的处理方法记录数组一共有几行几列,有多少不同的值。把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模。该小规模数组就是稀疏数组。应用实例五子棋棋盘二维数组存储,转为稀疏数组存储。二维数组转稀疏数组的实现思路遍历原始的二维数组,得到有效数据的原创 2020-07-25 17:13:51 · 358 阅读 · 1 评论