数据结构
文章平均质量分 78
详细数据结构知识
AJIUZ
这个作者很懒,什么都没留下…
展开
-
七大排序(Java)
目录一、插入排序1. 直接插入排序2. 希尔排序二、选择排序1. 直接选择排序 2. 堆排序 三、交换排序1. 冒泡排序 2. 快速排序四、归并排序五、总结 抓一张牌,在有序的牌中,找到合适的位置并且插入。 代码:2. 希尔排序 插入排序的升级版本,即进行大量的分组插排。代码:二、选择排序1. 直接选择排序 找到无序区间中最小的元素的下标,然后将该元素放到无序区间的开始(有序区间的最后)。代码: 2. 堆排序 选择排序的升级版本。将无序区间维护成一个大堆(因原创 2023-02-27 19:21:28 · 462 阅读 · 0 评论 -
优先级队列(PriorityQueue 和 Top-K问题)
java中提供了两种优先级队列:PriorityQueue 和 PriorityBlockingQueue。其中 PriorityQueue 是线程不安全的,PriorityBolckingQueue 是线程安全的。PriorityQueue 使用的是堆,且默认情况下是小堆——每次获取到的元素都是最小的元素。原创 2023-02-10 20:54:58 · 697 阅读 · 3 评论 -
java中对象的比较
1. ==:关于同一性比较2.equals:关于相等性比较3. Comparable接口:具备比较能力方法:intcompareTo(T o使用角度:使用已经实现了 Comparable接口的类的对象进行比较 ;定义类的角度:正确的重写了compraeTo方法。4. Comparator接口:用于比较两个东西的比较器方法:intcompare(T o1, T o2)使用角度:要比较的两个对象的类,不具备自然顺序,没有实现过 Comparable接口;要比较的两个对象的类,具备自然顺原创 2023-02-09 00:08:22 · 1110 阅读 · 0 评论 -
堆的基本操作及应用
1. 堆的基本操作:(1)向下调整:O(log(n))完全二叉树的高度(2)建堆:O(n)2. 优先级队列(堆的应用):(1)查看堆顶元素:O(1)(2)添加元素(向上调整):O(log(n))(3) 删除堆顶元素(替换 + 向下调整):O(log(n))原创 2023-02-06 18:25:42 · 628 阅读 · 0 评论 -
二叉树的前中后序遍历(非递归)
要实现前序遍历的非递归方式的思路:先循环遍历左子树,再遍历右子树。具体实现方法:第一次经过结点时就进行输出,但需要进行回溯,所以将经过的结点元素进行入栈。先遍历左子树,当最后一个结点的左孩子都为空时,判断最后一个结点的右子树。在代码中表示就为:遍历左子树时,若当前结点不为空则继续循环,若为空就说明需要判断当前结点的父母结点的右子树了,即需要进行回溯到上一个结点。回溯完成后,继续判断右子树的情况,即从右孩子继续判断:遍历右孩子的左子树,再按照相同方法遍历右孩子的右子树。所以需要两个变量,一个变量。原创 2023-02-05 22:19:32 · 396 阅读 · 0 评论 -
二叉树题目练习二(Java)
目录一、根据二叉树创建字符串二、给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。三、层序遍历四、根据一棵树的前序遍历和中序遍历构造一棵二叉树五、二叉树的构建及遍历题目:根据二叉树创建字符串 606.根据二叉树创建字符串 给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。 空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。 思路:(以示例1和示例原创 2023-02-03 22:14:35 · 124 阅读 · 0 评论 -
二叉树的层序遍历 + 通过层序遍历实现二叉树的操作
使用是将TreeNode 替换成 TreeNodeWithLevel,并且向队列中添加元素时,传入结点的同时,传入 level 层数即可。使用两个队列,一个队列存放结点,另一个队列存放相应的层数。需要注意的是两个队列对应的元素个数一样,所以在 while() 条件判断时,取任意一个队列的元素不为空即可。取出一个元素,就把其相应的左右孩子放入队列中(null 的不用放入)。使用带层数的层序遍历,当从队列中取出的元素的 level == k 时,size++。层序遍历,利用队列,每取出一个元素,size++原创 2023-01-04 17:33:53 · 620 阅读 · 0 评论 -
二叉树题目练习一(Java)
一、检查两棵树是否相同给你两棵二叉树的根节点p和q,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。二、是否是另一棵树的子树给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。三、翻转二叉树给你一棵二叉树的根节点root,翻转这棵四、判断一棵树是否是平衡二叉树五、判断两棵树是否互为镜像六、判断一棵树是否是对称二叉树原创 2022-12-18 21:45:21 · 263 阅读 · 0 评论 -
自己实现二叉树的基本操作(Java)
int size(TreeNode root) :获取树中结点个数。int getLeftNodeCount(TreeNode root) :获取叶子结点的个数。int getKLevelNodeCount(TreeNode root , int k) :获取第 k 层结点的个数。 int getHeight(TreeNode root) :获取二叉树的高度。boolean contians(TreeNode root , int val) :查找值为 val 的元素。聚合汇总思想原创 2022-12-17 23:22:19 · 961 阅读 · 0 评论 -
二叉树基本规律及其遍历
假设在一棵二叉树中,一共有 n0 个为度为 0 的结点,n1 个度为 1 的结点,n2 个度为 2 的结点。由于二叉树中所有结点的度只能是0、1、2,所以,整棵二叉树的结点个数 n = n0 + n1 + n2。当有剩余结点的完全二叉树的情况时, k = log₂ (n + 1) 计算出来的 k 一定为小数,则最终 k 为其整数部分 + 1 后的值。又因为每个结点都有一个双亲结点,即每一个结点都有一条连接双亲结点的边(根结点除外),所以总的边数为:结点个数 - 1。i = 0 为根结点,无双亲结点。原创 2022-12-16 21:42:19 · 1906 阅读 · 0 评论 -
设计循环队列(Java实现)(思路+图解+代码)
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。同时定义三个属性:size(队列中元素个数)、headIndex(指向队列的头)、lastIndex(指向下一个元素要插入的位置)。为了实现循环队列的特殊功能(利用这个队列之前用过的空间),所以删除数组的第一个元素和第二个元素。// 返回 false,队列已满。enQueue(value): 向循环队列插入一个元素。deQueue(): 从循环队列中删除一个元素。原创 2022-12-13 17:16:21 · 287 阅读 · 0 评论 -
自己实现队列的基本操作方法(Java实现)
自己通过链表实现队列的基本操作,同时定义一个内部类 Node 记录每个结点内存储的元素(value)以及下一个元素的结点(next)。并且定义一个头结点(head)和尾结点(last)方便后续的操作。观察三种情况,当队列中有元素时,都要进行头结点的更新。区别是尾结点的处理,元素个数为 1 个时,尾结点置空;元素个数大于1时,尾结点不变。因为队列先进先出,所以可以通过尾插操作来实现。因为队列先进先出,所以可以通过头删操作实现出队列操作。根据队列元素个数 size 判断即可。直接返回队列属性 size 值即可。原创 2022-12-12 10:33:44 · 762 阅读 · 2 评论 -
用栈实现队列(Java实现)(思路+图解+代码)
使用两个栈来实现,一个栈用来存放元素(stack1),一个栈用来取元素(stack2);boolean empty() 如果队列为空,返回 true;否则,返回 false。跟 pop 操作类似,只是最后不是将栈顶元素弹出,而只是查看(peek)。void push(int x) 将元素 x 推到队列的末尾。当 存放元素栈 和 取元素栈 同时为空时队列才为空。直接将元素放入 存放元素栈(stack1)即可。int pop() 从队列的开头移除并返回元素。int peek() 返回队列开头的元素。原创 2022-12-11 12:43:45 · 181 阅读 · 0 评论 -
用队列实现栈(Java实现)(思路+图示+代码)
将 存放元素队列 和 辅助队列 的指向进行调换,即此时 queue1 为 辅助队列,queue2 为 存储元素队列。将 存放元素队列 和 辅助队列 的指向进行调换,即此时 queue1 为 存放元素队列,queue2 为 辅助队列。查看栈顶元素操作,和 pop 操作类似,只是不删除元素,将 辅助队列 中的元素弹出后,再在 存放元素队列 中 传入这个元素,最后再进行引用的交换。则需要将前 size - 1 个元素放入 辅助队列中,然后将 存放元素队列 中剩下的一个元素(最后压入的一个元素)弹出栈(出队列)。原创 2022-12-10 23:40:57 · 885 阅读 · 1 评论 -
设计能在常数时间内检索到最小元素的栈(最小栈问题)
题目: 155.最小栈设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。实现 MinStack 类:MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。int getMin() 获取堆栈中的最小元素。示例:思路: 要能在常数时间内就能取到最小元素,考虑用一个额外的栈来存放最小值。主要考虑 push 操作和 pop 操作。思路一: 每压原创 2022-12-07 17:50:07 · 355 阅读 · 0 评论 -
使用Java中的栈和队列 + 栈习题
目录一、如何在Java中使用栈和队列。1. 操作队列的方法:2. 操作栈的方法:二、 关于栈的习题练习1. 有效的括号2. 逆波兰表达式求值3. 栈的压入、弹出序列(1) 创建队列: Queue queue = new LinkedList();(2) 入队列: queue.offer("×××"); (3) 出队列: String e = queue.poll();(4) 查看队首元素: String e = queue.peek();(5) 查看队列是否是空的(empty):原创 2022-12-06 18:10:44 · 345 阅读 · 2 评论 -
自己实现链表的基本操作方法(详细)(Java实现)
因为链表类也实现了线性表接口的方法,所以链表的基本操作方法和顺序表一样。这里我们定义链表中的元素类型为包装类(体现对象的形式而不是基本类型)这里提前定义了 MyNode 类,其中的属性为:Long val;三个属性,一个元素值 val ,一个指向前一个结点的引用 prev,一个指向后一个结点的引用 next。在 MyLinkedList 类(自定义链表类)中实现自定义基本方法,其中包括属性 MyNode head;int size;原创 2022-10-19 14:03:52 · 2454 阅读 · 0 评论 -
判断链表是否是回文链表(Java实现)
要想反转链表,需要三个引用,分别为 prev ( 记录前一个结点 )、cur ( 记录当前需要操作的结点 )、next ( 记录操作结点的后一个结点,因为改变 cur 指向的对象后,无法直接根据 cur 访问原来链表的下一个结点了)。我们这里使用找规律法:4 个元素的链表中间结点为第 3 个元素,需要从头结点开始跳 2 次;1.大体思路:找到链表的中间结点( mid ),再反转任意一半链表,变成两条链表。对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。原创 2022-10-17 17:55:14 · 546 阅读 · 0 评论 -
链表分割(将小于x的结点放在大于x结点之前)(详细)(Java实现)
2. 需要尾插操作,所以为了避免空指针异常,要分别定义两个工具结点,分别为 ans1 和ans2 的头结点和尾结点,头结点用来进行最后的合并,尾结点用来进行尾插结点。:定义两个逻辑上的链表( ans1 和 ans2),ans1 存小于 x 的结点,ans2 存大于 x 的结点。,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。这里直接使用 ans1 和 ans2 直接定义为头结点,最后直接返回 ans1.next 即可。原创 2022-10-16 21:28:44 · 306 阅读 · 0 评论 -
将两个升序链表合并成一个有序链表(Java实现)
3. 细化考虑,如何比较元素大小:依次分别取出两条链表中的第一个结点,进行比较,较小的那个先进行头删操作,再将这个结点(提前记录)尾插进合并后的链表( ans )中。2. 链表通过头结点来表示,说明当其中一个链表的头结点为 null 时,循环结束。循环结束后,将另一条链表剩下的元素依次尾插在合并后的链表( ans )中。( list1 == null || list2 == null )循环结束条件: list1 == null || list2 == null。将两个升序链表合并为一个新的。原创 2022-10-16 20:14:31 · 718 阅读 · 0 评论 -
输出链表中倒数第k个结点(双指针)(Java实现)
1 -> 2 -> 3 -> 4 -> 5 k = 1,size = 5,要跳 4 步。1 -> 2 -> 3 -> 4 -> 5 k = 3,size = 5,要跳 2 步。1.有关找结点的问题,要考虑链表中结点数不够的情况,即没有结点可找,返回 null。2.求出结点个数,再根据 k 值决定向后跳几步。输入一个链表,输出该链表中倒数第k个结点。输入:1,{1,2,3,4,5}总结出:x = size - k。定义前引用和后引用,同步进行。双指针法(前后引用)原创 2022-10-16 17:52:20 · 316 阅读 · 1 评论 -
返回链表的中间结点(非空单链表)(双指针法)(Java实现)
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.慢 -> 快 -> 判断 -> 快 -> 判断 (剩下两种情况类似)1 -> 3 -> 5 -> 7 返回 5 所在的结点,要跳 2 步。1 -> 3 -> 5 返回 3 所在的结点,要跳 1 步。输出:此列表中的结点 3 (序列化形式:[3,4,5])慢 ->判断 -> 快 -> 判断 -> 快。输入:[1,2,3,4,5,6]原创 2022-10-16 16:51:34 · 150 阅读 · 0 评论 -
206.反转链表 (Java实现)
4. 在本题中要注意返回值问题,应该返回头结点,但此时链表已经反转了,头结点不再是head。当遍历完后,cur引用已经指向null,所以应该返回他的前一个元素的引用prev。这里的特殊情况和普通情况一样,所以不需要做特殊处理。应该注意的是:最后 cur 指向 null ,而 prev 指向最后一个结点,所以应该。1. 每一个结点的指向都需要改变,所以要遍历整个链表,则循环条件: cur!3. 考虑特殊情况(第一个结点和最后一个结点)和普遍情况(中间结点)。,请你反转链表,并返回反转后的链表。原创 2022-10-16 15:33:21 · 513 阅读 · 0 评论 -
203.移除链表元素(删除链表中的重复元素)(Java实现)
prev 的移动:在进行删除后,prev 应该指向 cur 所指向的对象,但此时 cur 所指向的对象已经被删除,不在该链表里。所以,在删除后,prev引用的位置应该不变;不进行删除操作的时候,prev = cur。(1)删除的元素如果在第一个位置:要对 prev 引用进行解引用操作,但 prev 此时是 null,所以会出现 空指针异常!考虑两种情况:特殊位置(第一个结点和最后一个结点)和普遍位置(中间结点)(2)删除的元素在最后一个位置和中间位置均为普遍情况。删除元素:需要 cur 的前一个结点。原创 2022-10-15 21:15:39 · 898 阅读 · 0 评论 -
数据结构中List的继承体系(Iterable接口与Collection接口)
1. Iterable接口List是线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删改查以及变量等操作,这是List的逻辑角度。而从List的语法角度来看,它是一个接口。List接口继承自Collection接口,Collection接口继承自Iterable接口。1. Iterable接口Iterable接口中只有3个方法,这里用到的是抽象方法iterator()。原创 2022-10-05 19:07:28 · 1254 阅读 · 0 评论