数据结构部分

news2024/10/1 23:39:36

来源地址

一 数据结构

在这里插入图片描述

1 堆和树之间的区别

区别就在于树是没有特定顺序的,你需要遍历整个树才能找到特定元素;而堆是有序的,你可以直接找到最大(或最小)的元素。

堆:假设你正在开发一个任务调度系统,需要根据任务的优先级进行调度。你可以使用一个最小堆来实现任务队列,将任务按照优先级插入到堆中,并始终保持最小优先级的任务在堆顶部。这样,每次从堆顶部取出任务时,你总是能够获取到当前最高优先级的任务进行处理。

树结构:计算机的文件系统通常被组织成树状结构。根目录是整个文件系统的起点,每个文件夹可以包含子文件夹和文件,从而形成层次结构。

2 所有数据结构都是基于数组、链表或二者的组合实现的

基于数组实现的数据结构也称“静态数据结构”,这意味着此类数据结构在初始化后长度不可变。相对应地,基于链表实现的数据结构也称“动态数据结构”,这类数据结构在初始化后,仍可以在程序运行过程中对其长度进行调整。
在这里插入图片描述
在这里插入图片描述

3 基本数据类型

就是整数,浮点,字符,布尔类型:基本数据类型以二进制的形式存储在计算机中。一个二进制位即为 1 比特。在绝大多数现代操作系统中,1 字节(byte)由 8 比特(bit)组成。

基本数据类型提供了数据的“内容类型”,而数据结构提供了数据的“组织方式”。例如以下代码,我们用相同的数据结构(数组)来存储与表示不同的基本数据类型,包括 int、float、char、bool 等。

4 列表=“动态数组”

在这里插入图片描述

5 双向队列

在队列中,我们仅能删除头部元素或在尾部添加元素。如图 5-7 所示,「双向队列 double-ended queue」提供了更高的灵活性,允许在头部和尾部执行元素的添加或删除操作。
在这里插入图片描述

双向列表的应用

我们知道,软件的“撤销”功能通常使用栈来实现:系统将每次更改操作 push 到栈中,然后通过 pop 实现撤销。然而,考虑到系统资源的限制,软件通常会限制撤销的步数(例如仅允许保存 50 步)。当栈的长度超过 50 时,软件需要在栈底(队首)执行删除操作。但栈无法实现该功能,此时就需要使用双向队列来替代栈。请注意,“撤销”的核心逻辑仍然遵循栈的先入后出原则,只是双向队列能够更加灵活地实现一些额外逻辑。

6 哈希表 = 散列表

我们向哈希表中输入一个键 key ,则可以在 O(1) 时间内获取对应的值 value,实现高效的元素查询
在这里插入图片描述

1)哈希表的简单实现,仅用数组

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/02f9cb
在哈希算法中,将哈希值对桶数量(数组的长度)capacity 取模,是为了确定该 key 在数组中的索引位置。

取模运算是一种数学运算,它计算某个数除以另一个数的余数。在这个场景中,我们使用取模运算是为了将哈希值映射到数组的有效范围内。

作用如下:

  1. 均匀分布:通过取模运算,我们可以将哈希值均匀地映射到桶数组的各个索引位置上。这样可以避免将大部分数据集中在某几个桶中,提高散列的均匀性。

  2. 确定索引位置:取模运算得到的结果就是一个具体的索引位置,在数组中可以直接通过该索引访问或存储元素。这样可以快速定位到对应的桶,提高查找、插入、删除等操作的效率。

举个例子来说明:
假设有一个桶数组,长度为10(即capacity=10),而某个 key 经过哈希函数计算后得到的哈希值为 27。如果我们直接将哈希值作为索引,那么该 key 对应的索引位置就超出了数组的长度。但如果我们对容量取模(27 % 10),则得到的结果为 7,表示该 key 应该放在数组的第 7 个位置上。

所以,对容量取模可以将哈希值映射到合适的索引位置,确保数据分布均匀且能够准确定位到对应的桶。

2)哈希冲突

两key对应一个值了,这时候就需要扩容哈希表
「负载因子 load factor」是哈希表的一个重要概念,其定义为哈希表的元素数量除以桶数量,用于衡量哈希冲突的严重程度,也常作为哈希表扩容的触发条件。例如在 Java 中,当负载因子超过 0.75时,系统会将哈希表扩容至原先的 2倍。

哈希表的存储可能如下所示:
桶1: 空
桶2: 学生A, 85
桶3: 学生B, 92
桶4: 空
桶5: 学生C, 78
桶6: 空
桶7: 空
桶8: 空
桶9: 空
桶10: 空

哈希冲突会导致查询结果错误,严重影响哈希表的可用性。为了解决该问题,每当遇到哈希冲突时,我们就进行哈希表扩容,直至冲突消失为止。此方法简单粗暴且有效,但效率太低,因为哈希表扩容需要进行大量的数据搬运与哈希值计算。为了提升效率,我们可以采用以下策略。

1、改良哈希表数据结构,使得哈希表可以在出现哈希冲突时正常工作。
2、仅在必要时,即当哈希冲突比较严重时,才执行扩容操作。
哈希表的结构改良方法主要包括“链式地址”和“开放寻址”。
在这里插入图片描述
开放寻址有三法
在这里插入图片描述

7 树

二叉树的基本单元是节点,每个节点(父节点)包含值、左子节点引用(指针)和右子节点引用。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/683af95cb49f4463aa2e7a1ac4147077.png
插入和删除节点
在这里插入图片描述
在这里插入图片描述

遍历

在这里插入图片描述
前序遍历首先访问根节点,然后递归地遍历左子树和右子树
中序遍历先遍历左子树,然后访问根节点,最后遍历右子树
后序遍历先遍历左子树,然后遍历右子树,最后访问根节点
在这里插入图片描述

二叉搜索树

在这里插入图片描述

查找节点

从二叉树的根节点 root 出发,循环比较节点值 cur.val 和 num 之间的大小关系。

插入节点

也是先查找能插入节点的位置

在这里插入图片描述

AVL树

在这里插入图片描述

AVL树是一种自平衡二叉搜索树,它解决了普通二叉搜索树可能出现的性能问题。普通二叉搜索树在插入、删除操作频繁时,可能会变得不平衡,导致查找、插入、删除等操作的时间复杂度从O(logn)退化到O(n),严重影响了性能。

AVL树通过引入平衡因子(balance factor)来保持树的平衡状态。每个节点都有一个平衡因子,用来表示左子树和右子树的高度差。平衡因子可以为-1、0或1。当插入或删除节点后,AVL树会通过旋转操作,即左旋和右旋,来重新调整树的结构,使得每个节点的平衡因子保持在[-1, 0, 1]的范围内。

AVL树的特点如下:

  1. 每个节点的左子树和右子树的高度差最多为1,保证了树的平衡性。
  2. 查找、插入和删除操作的时间复杂度为O(logn),相较于普通二叉搜索树具有更好的性能保证。

通过保持树的平衡状态,AVL树能够提供快速的查找、插入和删除操作。然而,AVL树相对于普通二叉搜索树的平衡性要求更高,因为它需要频繁地进行旋转操作来维持平衡。这也使得AVL树在插入和删除操作时比较耗费时间。
在这里插入图片描述

8 堆

也是一种二叉树
堆(Heap)是一种特殊的树形数据结构,通常以完全二叉树的形式存在。它解决了在动态数据集中快速找到最大或最小元素的问题,并且能够高效地支持插入和删除操作。

堆有两种常见的形式:最大堆(Max Heap)和最小堆(Min Heap)。在最大堆中,父节点的值大于或等于其子节点的值;而在最小堆中,父节点的值小于或等于其子节点的值。

堆解决的问题是:

  1. 快速找到最大或最小元素:通过使用堆,可以保证根节点为最大(最大堆)或最小(最小堆)的元素。这样可以在O(1)的时间复杂度内找到最大或最小元素,而不需要遍历整个数据集。
  2. 高效支持插入和删除操作:堆具有自平衡的性质,当新元素插入或旧元素删除时,堆会自动进行调整,保持堆的性质。这样可以在O(logn)的时间复杂度内完成插入和删除操作,相较于其他排序或搜索算法更高效。

Top-k问题,选择堆是因为它的时间复杂度最小

在这里插入图片描述

def top_k_heap(nums: list[int], k: int) -> list[int]:
    """基于堆查找数组中最大的 k 个元素"""
    # 初始化小顶堆
    heap = []
    # 将数组的前 k 个元素入堆
    for i in range(k):
        heapq.heappush(heap, nums[i])
    # 从第 k+1 个元素开始,保持堆的长度为 k
    for i in range(k, len(nums)):
        # 若当前元素大于堆顶元素,则将堆顶元素出堆、当前元素入堆
        if nums[i] > heap[0]:
            heapq.heappop(heap)
            heapq.heappush(heap, nums[i])
    return heap

9 图

在这里插入图片描述

在这里插入图片描述

潜在好友推荐是社交网络分析中的一个常见问题,图可以用来实现这个功能。下面是一种基于图的潜在好友推荐的简单实现方法:

  1. 构建图:将社交网络中的用户表示为图的节点,用户之间的好友关系表示为图的边。每个节点可以附带用户的属性信息(如兴趣、职业等)。

  2. 确定目标用户:选择需要推荐好友的目标用户。

  3. 寻找邻居节点:从目标用户节点开始,遍历其直接连接的邻居节点,即其已有的好友。

  4. 排除已有好友:将目标用户已有的好友从候选节点列表中排除,以保证不会重复推荐已经是好友的人。

  5. 计算相似度:对于剩下的候选节点,计算它们与目标用户的相似度。可以使用各种相似度度量方法,如共同好友数量、兴趣爱好的匹配程度等。

  6. 推荐潜在好友:根据相似度评分,选择相似度高的候选节点作为潜在好友推荐给目标用户。

此方法仅是一种简单的示例,并且可能需要根据具体场景和需求进行改进和扩展。在实际应用中,可能会考虑更复杂的算法和更多的因素,如社区结构、用户行为等。同时,还可以使用图相关的算法和技术来提高潜在好友推荐的准确性和效果,如基于图的路径搜索、节点中心性分析等。

需要注意的是,潜在好友推荐是一个复杂的问题,涉及到数据隐私、算法设计等方面的考量,具体实现要根据具体情况进行权衡和规划。

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

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

相关文章

Java二叉树 (2)

🐵本篇文章将对二叉树的一些基础操作进行梳理和讲解 一、操作简述 int size(Node root); // 获取树中节点的个数int getLeafNodeCount(Node root); // 获取叶子节点的个数int getKLevelNodeCount(Node root,int k); // 获取第K层节点的个数int getHeight(Node r…

day06-网路编程

#include <myhead.h>int do_add(sqlite3 *ppDb) {int numb;char name[20];int age;int salary;printf("请输入要插入的信息:");scanf("%d %s %d %d", &numb, name, &age, &salary);char sql[128] "";sprintf(sql, "INSE…

Python算法(顺序查找/二分查找)

一。顺序查找法&#xff1a; 用途&#xff1a;主要用于查找无序的列表的某个元素 时间复杂度为O(n) 拓展&#xff1a;函数index&#xff08;&#xff09;运用的是顺序查找 二。二分查找法&#xff1a; 前提&#xff1a;被查找的列表顺序一定要是顺序的 用途&#xff1a;对…

java数值运算a/0 ;0/b; 0/0;结果

3/0indinity 无穷大 0/40 0/0NaN 不定值

JVM 常用监控工具介绍和使用

一、JPS 进程查看工具 用于列出当前系统中所有正在运行的 Java 进程。它的主要作用是查看 Java 进程的 PID&#xff08;进程标识符&#xff09;和主类名。可以帮助开发人员快速了解系统中正在运行的 Java 进程&#xff0c;对于监控和调试 Java 应用程序非常有用。 用法&#…

官网:所谓高大上,无非是把核心突出到了极致。

2023-10-30 14:37贝格前端工场 企业官网建设&#xff0c;客户往往要求高大上&#xff0c;但是很多设计师对高大上的解读存在了偏差&#xff0c;以至于设计的网站客户不满意&#xff0c;其实抓住官网所要展现的核心点&#xff0c;把核心点展现到极致&#xff0c;就是高大上。 …

Bee Mobile组件库重磅升级

Bee Mobile组件库重磅升级&#xff01; 丰富强大的组件移动预览快速上手create-bee-mobile Bee Mobile组件库重磅升级&#xff01; Bee Mobile组件库最新 v1.0.0 版本&#xff0c;支持最新的 React v18。 主页&#xff1a;Bee Mobile 丰富强大的组件 一共拥有50多个组件&…

果蔬作物疾病防治系统|基于Springboot的果蔬作物疾病防治系统设计与实现(源码+数据库+文档)

果蔬作物疾病防治系统目录 目录 基于Springboot的果蔬作物疾病防治系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、果蔬百科列表 2、公告信息管理 3、公告类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推…

Opencv 绘制线段、矩形、圆形、多边形操作

1、前言 OpenCV提供了许多用于绘制图形的方法 包括绘制线段的line()方法、绘制矩形的 rectangle()方法、绘制圆形的 circle()方法、绘制多边形的 polylines()方法和绘制文字的 putText()方法 本章将依次对上述各个方法进行讲解&#xff0c;并作出相应实验。 因为 OpenCV 中的…

ES分页查询的最佳实践:三种方案

Elasticsearch&#xff08;ES&#xff09;中进行分页查询时&#xff0c;最佳实践取决于具体的使用场景和需求。 以下是对每种分页方法的简要分析以及它们适用的情况&#xff1a; 1. From Size 最常见且直观的方法&#xff0c;通过from参数指定跳过多少条记录&#xff0c;si…

服务器-->网站制作-->接口开发,一篇文章一条龙服务(2)

作者&#xff1a;q: 1416279170v: lyj_txd前述&#xff1a;本人非专业&#xff0c;兴趣爱好自学自研&#xff0c;很多没有说清楚的地方见谅&#xff0c;欢迎一起讨论的小伙伴~ 上期回顾&#xff0c;了解 服务器&#xff0c;网站制作&#xff0c;接口开发之见的关系&#xff0c…

UDP与TCP:了解这两种网络协议的不同之处

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

挑战杯 基于设深度学习的人脸性别年龄识别系统

文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习机器视觉的…

使用 Python 字典向 SQLite 插入数据

将Python字典数据插入SQLite数据库中其实有很多好处&#xff0c;例如使用字典的结构可以简化插入数据的代码&#xff0c;使其更加紧凑和易于理解。这降低了代码的复杂性&#xff0c;并使代码更易于维护。那么在我们日常使用中会有哪些问题呢&#xff1f;一起看看我是如何解决的…

子类的继承性

继承性 类有两种重要的成员&#xff1a; 成员变量和方法 子类的成员 ① 自己声明定义 ②从父类继承 ① 成员变量的继 把继承来的变量作为 自己的一个成员变量 &#xff08;如同在子类中直接声明一样&#xff09;&#xff1b; 可被子类中自定义的任何实例方法操作 。 ② 方法…

装windows11+centos双系统时遇到问题及解决方法

从u盘启动提示linpus lite has been blocked 首先下载iso镜像文件&#xff0c;制作u盘启动工具&#xff0c;进行启动&#xff0c;这里进入bios界面进行启动项选择后&#xff0c;虽然已经将usb作为首要启动值 却会出现上图所示被“block”情形 需要在bios界面security选项&…

启发式算法:遗传算法

文章目录 遗传算法-引例交叉变异遗传算法遗传算法流程遗传算法应用遗传算法-引例 在一代代演化过程中,父母扇贝的基因组合产生新扇贝,所以遗传算法会选择两个原有的扇贝,然后对这两个扇贝的染色体进行随机交叉形成新的扇贝。迭代演化也会造成基因突变,遗传算法让新产生扇贝…

小程序网页view多行文本超出隐藏或显示省略号

实现效果&#xff1a; 限制两行&#xff0c;超出即显示省略号 实现&#xff1a;话不多说&#xff0c;展示代码 关键代码 .box{ width:100rpx; overflow:hidden; text-overflow: ellipsis;//超出省略号 display:-webkit-box; -webkit-line-clamp: 2;//显…

uniapp让输入框保持聚焦状态,不会失去焦点

使用场景&#xff1a;当输入框还有发送按钮的时候&#xff0c;点击发送希望软键盘不消失&#xff0c;还可以继续输入&#xff0c;或者避免因输入图片标签造成的屏闪问题 多次尝试后发现一个很实用的方法&#xff0c;适用input输入框和editor输入框 解决办法&#xff1a;把cli…

python基础——条件判断和循环【if,while,for,range】

&#x1f4dd;前言&#xff1a; 这篇文章主要讲解一下条件判断语句if和循环语句while&#xff0c;for在python中需要注意的地方。 建议已有一定了解&#xff08;对语句的执行逻辑清楚&#xff09;的读者观看&#xff0c;如果对条件判断和循环的执行逻辑不太清楚&#xff0c;也可…