读书笔记-《数据结构与算法》-摘要1[数据结构]

文章目录

  • [数据结构]
    • 1. String - 字符串
    • 2. Linked List - 链表
      • 2.1 链表的基本操作
      • 2.1.1 反转链表
        • 单向链表
        • 双向链表
      • 2.1.2 删除链表中的某个节点
      • 2.1.3 链表指针的鲁棒性
      • 2.1.4 快慢指针
    • 3. Binary Tree - 二叉树
      • 3.1 树的遍历
      • 3.2 Binary Search Tree - 二叉查找树
    • 4. Queue - 队列
      • 4.1 Queue - 队列
      • 4.2 Priority Queue - 优先队列
      • 4.3 Deque - 双端队列
    • 5. Heap - 堆
    • 6. Stack - 栈
    • 7. Set
    • 8. Map - 哈希表
    • 9. Graph - 图

[数据结构]

1. String - 字符串

开发常用,没啥可说的,注意的是字符串拼接时,可能会用到 StringBuffer 与 StringBuilder,前者保证线程安全,后者不是,但单线程下效率高一些,一般使用 StringBuilder。

2. Linked List - 链表

链表是线性表的一种。线性表是最基本、最简单、也是最常用的一种数据结构。

线性表有两种存储方式,一种是顺序存储结构(例如数组),另一种是链式存储结构。

链式存储结构就是两个相邻的元素在内存中可能不是相邻的,每一个元素都有一个指针域,指针域一般是存储着到下一个元素的指针。这种存储方式的优点是插入和删除的时间复杂度为 O(1),缺点是访问的时间复杂度最坏为 O(n)。

链表就是链式存储的线性表。根据指针域的不同,链表分为单向链表、双向链表、循环链表等等。

2.1 链表的基本操作

2.1.1 反转链表

单向链表

链表的基本形式是:1 -> 2 -> 3 -> null,反转需要变为 3 -> 2 -> 1 -> null。这里要注意:

  • 访问某个节点 curt.next 时,要检验 curt 是否为 null。
  • 要把反转后的最后一个节点(即反转前的第一个节点)指向 null。
class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;}
}public ListNode reverse(ListNode head) {ListNode prev = null;while (head != null) {ListNode next = head.next;head.next = prev;prev = head;head = next;}return prev;
}
双向链表

和单向链表的区别在于:双向链表的反转核心在于nextprev域的交换,还需要注意的是当前节点和上一个节点的递推。

class DListNode {int val;DListNode prev, next;DListNode(int val) {this.val = val;this.prev = this.next = null;}
}public DListNode reverse(DListNode head) {DListNode curr = null;while (head != null) {curr = head;head = curr.next;curr.next = curr.prev;curr.prev = head;}return curr;
}

2.1.2 删除链表中的某个节点

删除链表中的某个节点一定需要知道这个点的前继节点,所以需要一直有指针指向前继节点。还有一种删除是伪删除,是指复制一个和要删除节点值一样的节点,然后删除,这样就不必知道其真正的前继节点了。

然后只需要把 prev -> next = prev -> next -> next 即可。

2.1.3 链表指针的鲁棒性

综合上面讨论的两种基本操作,链表操作时的鲁棒性问题主要包含两个情况:

  • 当访问链表中某个节点 curt.next 时,一定要先判断 curt 是否为 null。
  • 全部操作结束后,判断是否有环;若有环,则置其中一端为 null

2.1.4 快慢指针

所谓快慢指针中的快慢指的是指针向前移动的步长,每次移动的步长较大即为快,步长较小即为慢,常用的快慢指针一般是在单链表中让快指针每次向前移动2,慢指针则每次向前移动1。快慢两个指针都从链表头开始遍历,于是快指针到达链表末尾的时候慢指针刚好到达中间位置,于是可以得到中间元素的值。快慢指针在链表相关问题中主要有两个应用:

  • 快速找出未知长度单链表的中间节点 设置两个指针 *fast*slow 都指向单链表的头节点,其中*fast的移动速度是*slow的2倍,当*fast指向末尾节点的时候,slow正好就在中间了。
  • 判断单链表是否有环 利用快慢指针的原理,同样设置两个指针 *fast*slow 都指向单链表的头节点,其中 *fast的移动速度是*slow的2倍。如果 *fast = NULL,说明该单链表 以 NULL结尾,不是循环链表;如果 *fast = *slow,则快指针追上慢指针,说明该链表是循环链表。

3. Binary Tree - 二叉树

二叉树是每个节点最多有两个子树的树结构,子树有左右之分,二叉树常被用于实现二叉查找树二叉堆

public class TreeNode {public int val;public TreeNode left, right;public TreeNode(int val) {this.val = val;this.left = null;this.right = null;}
}

3.1 树的遍历

从二叉树的根节点出发,节点的遍历分为三个主要步骤:对当前节点进行操作(称为“访问”节点,或者根节点)、遍历左边子节点、遍历右边子节点。访问节点顺序的不同也就形成了不同的遍历方式。需要注意的是树的遍历通常使用递归的方法进行理解和实现,在访问元素时也需要使用递归的思想去理解。实际实现中对于前序和中序遍历可尝试使用递归实现。

按照访问根元素(当前元素)的前后顺序,遍历方式可划分为如下几种:

  • 深度优先:先访问子节点,再访问父节点,最后访问第二个子节点。根据根节点相对于左右子节点的访问先后顺序又可细分为以下三种方式。
    1. 前序(pre-order):先根后左再右
    2. 中序(in-order):先左后根再右
    3. 后序(post-order):先左后右再根
  • 广度优先:先访问根节点,沿着树的宽度遍历子节点,直到所有节点均被访问为止。

3.2 Binary Search Tree - 二叉查找树

一颗二叉查找树(BST)是一颗二叉树,其中每个节点都含有一个可进行比较的键及相应的值,且每个节点的键都大于等于左子树中的任意节点的键,而小于右子树中的任意节点的键

使用中序遍历可得到有序数组,这是二叉查找树的又一个重要特征。

二叉查找树使用的每个节点含有两个链接,它是将链表插入的灵活性和有序数组查找的高效性结合起来的高效符号表实现。

4. Queue - 队列

4.1 Queue - 队列

Queue 是一个 FIFO(先进先出)的数据结构,并发中使用较多,可以安全地将对象从一个任务传给另一个任务。

Queue 在 Java 中是 Interface, 一种实现是 LinkedList 向上转型为 Queue, Queue 通常不能存储 null 元素,否则与 poll() 等方法的返回值混淆。

Queue<Integer> q = new LinkedList<Integer>();
int qLen = q.size(); // get queue length
0:0Throws exceptionReturns special value
Insertadd(e)offer(e)
Removeremove()poll()
Examineelement()peek()

优先考虑右侧方法,右侧元素不存在时返回 null. 判断非空时使用isEmpty()方法,继承自 Collection.

import java.util.LinkedList;
import java.util.Queue;public class QueueMethods {public static void main(String[] args) {Queue<Integer> q = new LinkedList<>();q.offer(1); // 增加元素q.offer(2); // 增加元素q.add(3); // 增加元素q.add(4); // 增加元素int size = q.size(); // 获取长度System.out.println("原始 q:" + q);/** remove 移除 Queue 的头部元素,并返回移除的元素* 移除时若队列为空,则报错:NoSuchElementException* 这也是它与 pull 方法的区别*/Integer remove = q.remove();System.out.println("remove 后 获取的元素 remove:" + remove);System.out.println("remove 后 q:" + q);Integer poll = q.poll();System.out.println("poll 后 获取的元素 poll:" + poll);System.out.println("poll 后 q:" + q);/** element 获取 Queue 的头部元素,并返回移除的元素* 移除时若队列为空,则报错:NoSuchElementException* 这也是它与 peek 方法的区别*/Integer element = q.element();System.out.println("element 后 获取的元素 element:" + element);System.out.println("element 后 q:" + q);Integer peek = q.peek();System.out.println("peek 后 获取的元素 peek:" + peek);System.out.println("peek 后 q:" + q);// 判断队列是否为空boolean empty = q.isEmpty();System.out.println("q 是否为空:" + empty);}
}

输出:

原始 q:[1, 2, 3, 4]
remove 后 获取的元素 remove:1
remove 后 q:[2, 3, 4]
poll 后 获取的元素 poll:2
poll 后 q:[3, 4]
element 后 获取的元素 element:3
element 后 q:[3, 4]
peek 后 获取的元素 peek:3
peek 后 q:[3, 4]
q 是否为空:false

在这里插入图片描述

(图网,侵删)

4.2 Priority Queue - 优先队列

应用程序常常需要处理带有优先级的业务,优先级最高的业务首先得到服务。因此优先队列这种数据结构应运而生。优先队列中的每个元素都有各自的优先级,优先级最高的元素最先得到服务;优先级相同的元素按照其在优先队列中的顺序得到服务。

优先队列可以使用数组或链表实现,从时间和空间复杂度来说,往往用二叉堆来实现。

Java 中提供PriorityQueue类,该类是 Interface Queue 的另外一种实现,和LinkedList的区别主要在于排序行为而不是性能,基于 priority heap 实现,非synchronized,故多线程下应使用PriorityBlockingQueue. 默认为自然序(小根堆),需要其他排序方式可自行实现Comparator接口,选用合适的构造器初始化。使用迭代器遍历时不保证有序,有序访问时需要使用Arrays.sort(pq.toArray()).

4.3 Deque - 双端队列

双端队列(deque,全名double-ended queue)可以让你在任何一端添加或者移除元素,因此它是一种具有队列和栈性质的数据结构。

Java 在1.6之后提供了 Deque 接口,既可使用ArrayDeque(数组)来实现,也可以使用LinkedList(链表)来实现。前者是一个数组外加首尾索引,后者是双向链表。

Deque<Integer> deque = new ArrayDeque<Integer>();
First Element (Head)Last Element (Tail)
Throws exceptionSpecial valueThrows exceptionSpecial value
InsertaddFirst(e)offerFirst(e)addLast(e)offerLast(e)
RemoveremoveFirst()pollFirst()removeLast()pollLast()
ExaminegetFirst()peekFirst()getLast()peekLast()

其中offerLast和 Queue 中的offer功能相同,都是从尾部插入。

5. Heap - 堆

一般情况下,堆通常指的是二叉堆二叉堆是一个近似完全二叉树的数据结构,即披着二叉树羊皮的数组,故使用数组来实现较为便利。子结点的键值或索引总是小于(或者大于)它的父节点,且每个节点的左右子树又是一个二叉堆(大根堆或者小根堆)。根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常被用作实现优先队列。

堆的基本操作

以大根堆为例,堆的常用操作如下。

  1. 最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
  2. 创建最大堆(Build_Max_Heap):将堆所有数据重新排序
  3. 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

其中步骤1是给步骤2和3用的。

在这里插入图片描述

—PS:这本书里有很多这种动图,简直就是神器

6. Stack - 栈

栈是一种 LIFO(Last In First Out) 的数据结构,常用方法有添加元素,取栈顶元素,弹出栈顶元素,判断栈是否为空。

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Stack;public class StackMethods {public static void main(String[] args) {/** JDK doc 中建议使用Deque代替Stack实现栈,* 因为Stack继承自Vector,需要synchronized,性能略低。*/Stack<Integer> stack = new Stack<>();Deque<Integer> s = new ArrayDeque<>();// E push(E item) - 向栈顶添加元素s.push(1);s.push(2);s.push(3);System.out.println("原始栈:" + s);System.out.println("原始栈,长度:" + s.size());// E peek() - 取栈顶元素,不移除Integer peek = s.peek();System.out.println("获取的栈顶元素:" + peek);System.out.println("peek 栈,长度:" + s.size());// E pop() - 移除栈顶元素并返回该元素Integer pop = s.pop();System.out.println("获取的栈顶元素:" + pop);System.out.println("pop 栈,长度:" + s.size());// 判断栈是否为空,若使用 Stack 类构造则为 empty()System.out.println("Deque 创建栈是否为空:" + s.isEmpty());System.out.println("Stack 创建栈是否为空:" + stack.empty());}
}

输出:

原始栈:[3, 2, 1]
原始栈,长度:3
获取的栈顶元素:3
peek 栈,长度:3
获取的栈顶元素:3
pop 栈,长度:2
Deque 创建栈是否为空:false
Stack 创建栈是否为空:true

7. Set

Set 是一种用于保存不重复元素的数据结构。常被用作测试归属性,故其查找的性能十分重要。

Set 与 Collection 具有安全一样的接口,通常有HashSet, TreeSetLinkedHashSet三种实现。HashSet基于散列函数实现,无序,查询速度最快;TreeSet基于红-黑树实现,有序。

8. Map - 哈希表

Map 是一种关联数组的数据结构,也常被称为字典或键值对。

Java 的实现中 Map 是一种将对象与对象相关联的设计。常用的实现有HashMapTreeMap, HashMap被用来快速访问,而TreeMap则保证『键』始终有序。Map 可以返回键的 Set, 值的 Collection, 键值对的 Set.

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("bill", 98);
map.put("ryan", 99);
boolean exist = map.containsKey("ryan"); // check key exists in map
int point = map.get("bill"); // get value by key
int point = map.remove("bill") // remove by key, return value
Set<String> set = map.keySet();
// iterate Map
for (Map.Entry<String, Integer> entry : map.entrySet()) {String key = entry.getKey();int value = entry.getValue();// do some thing
}

9. Graph - 图

图的表示通常使用邻接矩阵和邻接表,前者易实现但是对于稀疏矩阵会浪费较多空间,后者使用链表的方式存储信息但是对于图搜索时间复杂度较高。

/* Java Definition */
int[][] g = new int[V][V];

在这里插入图片描述
(图网,侵删)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/198473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSP入门+EL表达式+JSTL标签

1.JSP&#xff1a; 1.指令 2.注释 3.内置对象 2.MVC开发模式 3.EL表达式 4.JSTL标签 5.三层架构 ## JSP&#xff1a; 1.指令 *用于配置JSP页面&#xff0c;导入资源文件 *格式&#xff1a;<% 指令名称 属性名1属性值1 属性名2属性值2 .......%> *分类&#xff1…

vue项目使用js监听浏览器关闭、刷新、后退事件

业务场景 在Web应用开发中&#xff0c;我们经常会遇到这样的需求&#xff1a;在用户执行关键操作&#xff0c;如提交表单、支付交易等过程中&#xff0c;突然关闭、刷新或者后退浏览器&#xff0c;可能会导致操作未完成或者数据丢失。为了提高用户体验和保证应用数据的完整性&…

格雷希尔帮助仪器仪表测试时快速密封的G60C系列接头其优势有哪些

仪器仪表在工业领域中扮演着重要的角色&#xff0c;如&#xff1a;压力表&#xff0c;压力传感器、压力变送器、压力开关、压力歧管等这些&#xff0c;在工业领域中都是随处可见的&#xff0c;其数据的精度直接影响着产品在生产过程中的质量和安全性&#xff1b;因此&#xff0…

day4 检测链表的环入口

ListNode *detectCycle(ListNode *head) { ListNode* fast head; ListNode* slow head; while(fast ! NULL && fast->next ! NULL) { slow slow->next; fast fast->next->next; // 快慢指针相遇&#xff0c;此…

8-Hive原理与技术

单选题 题目1&#xff1a;按粒度大小的顺序&#xff0c;Hive数据被分为&#xff1a;数据库、数据表、桶和什么 选项: A 元祖 B 栏 C 分区 D 行 答案&#xff1a;C ------------------------------ 题目2&#xff1a;以下选项中&#xff0c;哪种类型间的转换是被Hive查询语言…

fastadmin嵌套关联查询,thinkPHP5嵌套关联查询

fastadmin嵌套关联查询 thinkPHP5嵌套关联查询 笔记记录 嵌套关联查询 A -> B -> C A 表关联B表 B表关联C表 同时把A&#xff0f;B&#xff0f;C表相关的数据展现出来 B表的model B表关联C表 我的C表是B表的自身关联。也是一个表&#xff0c;所以为C表 namespace app…

食品行业研究:金枪鱼产业发展及市场消费分析

金枪鱼是无污染、高档、美味、安全、健康的绿色海洋动物食品&#xff0c;是国际营养协会推荐的世界三大营养鱼种之一 ,它凭借较高的经济价值、较广的分布范围、丰富的资源储量等优势&#xff0c;成为当今世界远洋渔业发展的关注重点和国际水产品贸易的主要鱼种。 金枪鱼类是高度…

【重点】41.缺失的第一个正数

题目 法1&#xff1a;哈希表 实际上&#xff0c;对于一个长度为N的数组&#xff0c;其中没有出现的最小正整数只能在 [1, N 1]中。这是因为如果[1, N] 都出现了&#xff0c;那么答案是 N 1&#xff0c;否则答案是[1, N] 中没有出现的最小正整数。 class Solution {public …

3分钟,全方面了解透明oled拼接屏

透明OLED拼接屏是一种先进的显示技术&#xff0c;它具有透明度高、色彩鲜艳、轻薄柔韧、拼接灵活、功耗低、寿命长等特点。在商业、教育、展示、娱乐等领域&#xff0c;透明OLED拼接屏的应用越来越广泛。 在商业领域&#xff0c;透明OLED拼接屏可以作为商品展示柜&#xff0c;通…

【android开发-07】android中ImageView的用法介绍

1&#xff0c;ImageView使用drawable图片的方法 ImageView是Android开发中常用的视图控件&#xff0c;用于显示图片资源。ImageView继承自View类&#xff0c;可以用于展示Bitmap或Drawable类型的图片资源。 ImageView可以通过XML属性设置显示图片&#xff0c;也可以通过Java代…

关于webpack 的面试知识点

一、什么是loader?有哪些常见的loader?怎么配置&#xff1f; loader 可以理解成翻译官&#xff0c;webpack,只能识别js&#xff0c;其它的文件&#xff0c;就需要loader 来解析 常见的loader有&#xff1a; babel-loader(处理es6)、css-loader、style-loader&#xff08;将cs…

系统运维工具KSysAK——让运维回归简单

系统运维工具KSysAK——让运维回归简单 1.基本信息 1.1概述 系统异常定位分析工具KSysAK是云峦操作系统研发及运维人员总结开发及运维经验&#xff0c;设计和研发的多个运维工具的集合&#xff0c;可以覆盖系统的日常监控、线上问题诊断和系统故障修复等常见运维场景。 工具…

从一个bug认识 Spring 单例模式

大家好&#xff0c;我是风筝&#xff0c;公众号「古时的风筝」 谁还没在 Spring 里栽过跟头呢&#xff0c;从哪儿跌倒&#xff0c;就从哪儿睡一会儿&#xff0c;然后再爬起来。 讲点儿武德 这是由一个真实的 bug 引起的&#xff0c;bug 产生的原因就是忽略了 Spring Bean 的…

网络层之无分类编址CIDR(内涵计算例题)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

初学vue3与ts:element-plus的警告(Extraneous non-props attributes (ref_key) ...)

用了vue3与ts&#xff0c;ui我就选了element-plus element-plus官网&#xff1a;https://element-plus.org/zh-CN/ element-plus官网(国内镜像站点)&#xff1a;https://element-plus.gitee.io/zh-CN/ 国内镜像站点如果进不去的话&#xff0c;在element-plus官网最下面的链接-&…

Jupyter Notebook中设置Cell主题

1. 获取本机Jupyter的配置目录 C:\Users\Administrator>jupyter --data-dir C:\Users\Administrator\AppData\Roaming\jupyter2. 进入获取的目录&#xff0c;创建指定路径 C:\Users\Administrator>cd C:\Users\Administrator\AppData\Roaming\jupyter C:\Users\Adminis…

【华为OD】某通信网络中有N个网络节点,用1到N进行标识。 网络通过一个有向无环图表示,其中图的边的值表示结点之间的消息传递时延。

某通信网络中有N个网络节点,用1到N进行标识。网络通过一个有向无环图表示,其中图的边的值表示结点之间的消息传递时延。现给定相连节点之间的时延列表times[i] = {u,v,w},u表示源节点,v表示目的节点,w表示u和v之间的消息传递时延。请计算给定源节点到目的节点的最小传输时…

vue3 Composition API

Vue3 Composition API 是 Vue.js 的新版本中引入的一种新特性&#xff0c;它允许开发者更灵活地组织和重用代码。Composition API 提供了一种新的方式来组织组件逻辑&#xff0c;使得代码更加模块化和可维护。 以下是示例&#xff1a; <template><div>{{ count }…

TikTok新闻视角:短视频如何改变信息传递方式?

随着数字时代的不断发展&#xff0c;信息传递的方式也在不断演变。近年来&#xff0c;短视频平台TikTok崭露头角&#xff0c;通过其独特的15秒短视频形式&#xff0c;逐渐在新闻传播领域占据一席之地。本文将深入探讨TikTok在新闻视角下是如何改变信息传递方式的&#xff0c;以…

计算机毕设:基于机器学习的生物医学语音检测识别 附完整代码数据可直接运行

项目视频讲解: 基于机器学习的生物医学语音检测识别 完整代码数据可直接运行_哔哩哔哩_bilibili 运行效果图: 数据展示: 完整代码: #导入python的 numpy matplotlib pandas库 import pandas as pd import numpy as np import matplotlib.pyplot as plt #绘图 import se…