Hello 算法 1.0.0b4 C++版5.4. 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 6. 散列表 92 6.1. 哈希表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 本书主要内容包括: ‧ 复杂度分析:数据结构和算法的评价维度,算法效率的评估方法。时间复杂度、空间复杂度的推算方 法、常见类型、示例等。 ‧ 数据结构:基本数据类型,数据结构的分类方法。数组、链表、栈、队列、散列表、树、堆、图等数据 结构的定义、优缺点、常用操作、常见类型、典型应用、实现方法等。 ‧ 算法:搜索、排序、分治、回溯、动态规划、贪心等算法的定义、优缺点、效率、应用场景、解题步骤、 示例题目等。 等编程语言默认使用 UTF‑16 编码。 3.5.1. Q & A � 为什么哈希表同时包含线性数据结构和非线性数据结构? 哈希表底层是数组,而为了解决哈希冲突,我们可能会使用“拉链法”(后续散列表章节会讲)。 在拉链法中,数组中每个地址(桶)指向一个链表;当这个链表长度超过一定阈值时,又可能 被转化为树(通常为红黑树)。因此,哈希表可能同时包含线性(数组、链表)和非线性(树) 数据结构。0 码力 | 343 页 | 27.39 MB | 1 年前3
Hello 算法 1.0.0b1 C++版4. 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 6. 散列表 82 6.1. 哈希表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 复杂度分析:数据结构与算法的评价维度、算法效率的评估方法。时间复杂度、空间复杂度,包括推算 方法、常见类型、示例等。 ‧ 数据结构:常用的基本数据类型,数据在内存中的存储方式、数据结构分类方法。数组、链表、栈、队列、 散列表、树、堆、图等数据结构,内容包括定义、优劣势、常用操作、常见类型、典型应用、实现方法等。 ‧ 算法:查找算法、排序算法、搜索与回溯、动态规划、分治算法,内容包括定义、使用场景、优劣势、时 空效率、实现方法、示例题目等。 且可以灵活地修改长度;但结点访问效率低、占用 内存多。常见的链表类型有单向链表、循环链表、双向链表。 ‧ 列表又称动态数组,是基于数组实现的一种数据结构,其保存了数组的优势,且可以灵活改变长度。列 表的出现大大提升了数组的实用性,但副作用是会造成部分内存空间浪费。 ‧ 下表总结对比了数组与链表的各项特性。 数组 链表 存储方式 连续内存空间 离散内存空间 数据结构长度 长度不可变 长度可变0 码力 | 187 页 | 14.71 MB | 1 年前3
Hello 算法 1.0.0b2 C++版4. 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 6. 散列表 82 6.1. 哈希表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 复杂度分析:数据结构与算法的评价维度、算法效率的评估方法。时间复杂度、空间复杂度,包括推算 方法、常见类型、示例等。 ‧ 数据结构:常用的基本数据类型,数据在内存中的存储方式、数据结构分类方法。数组、链表、栈、队列、 散列表、树、堆、图等数据结构,内容包括定义、优劣势、常用操作、常见类型、典型应用、实现方法等。 ‧ 算法:查找算法、排序算法、搜索与回溯、动态规划、分治算法,内容包括定义、使用场景、优劣势、时 空效率、实现方法、示例题目等。 且可以灵活地修改长度;但结点访问效率低、占用 内存多。常见的链表类型有单向链表、循环链表、双向链表。 ‧ 列表又称动态数组,是基于数组实现的一种数据结构,其保存了数组的优势,且可以灵活改变长度。列 表的出现大大提升了数组的实用性,但副作用是会造成部分内存空间浪费。 ‧ 下表总结对比了数组与链表的各项特性。 数组 链表 存储方式 连续内存空间 离散内存空间 数据结构长度 长度不可变 长度可变0 码力 | 197 页 | 15.72 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 09 CUDA C++ 流体仿真实战各维度上的大小通过 cudaExtent 指定,方 便起见我们的 C++ 封装类用了 uint3 表示 大小。 • GPU 的多维数组有特殊的数据排布来保障 访存的高效,和我们 CPU 那样简单地行主 序或列主序(如 a[x + nx * y] )的多维数组 不一样。 • 随后可用 cudaMemcpy3D 在 GPU 的三 维数组和 CPU 的三维数组之间拷贝数据。 CUDA 表面对象:封装 • clr 和 vel 使用了双缓冲,写入 clrNext 的同时读取 clr 没有冲突,写入完毕后对调 clrNext 和 clr 。 投影部分 投影部分 • 我们要模拟的流体是不可压缩的,因此有着无散度的特点: div v = 0 • 上式对时间求导,即 d(div v)/dt = div dv/dt = 0 ;带入 dv/dt = -p 得 div grad p = 0 。 • 因此为了模拟不可压缩流我们要求保证 的速度散度 。 投影部分:求速度的散度 • 第一步,如何求出速度场的散度呢?首先速度是一个矢量场,为了 CUDA 对齐方便我们用 了 float4 表示三维矢量,因此速度场在 CUDA 看来就是一个元素类型为 float4 的三维数 组。其散度则是一个标量场,用元素类型为 float 的三维数组来表示。 • 定义求散度的核函数,首先读取速度场周围六个元素的值,然后上下做差得到散度。 投影部分:0 码力 | 58 页 | 14.90 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化float a[n]; 可以在栈上分配有 n 个元素的一维数组。 • 通过 a[i] 访问第 i 个元素。 • float a[n][m]; 可以在栈上分配 n 行 m 列的二维数组。 • 通过 a[i][j] 访问第 i 行,第 j 列的元素。 等一下……内存是一维的,为什么可以分配二维的数组? • 众所周知,内存是一维的,因此任何二维数组,都必须被扁平化,才能储存在内存中。 • 对于 float 可以在栈上分配有 n 个元素的一维数组。 • 通过 a[i] 访问第 i 个元素。 • array, m> a; 可以在栈上分配 n 行 m 列的二维数组。 • 通过 a[i][j] 访问第 i 行,第 j 列的元素。 • array 和 C 语言的 [] 数组相比,好处是作为参数传入时不会退化成指针。 C 语言动态数组 • float *a = malloc(n * • 通过 a[i] 访问第 i 个元素。 • float *a = malloc(n * m * sizeof(float)); 可以在堆上分配 n 行 m 列的二维数组。 • 通过 a[i * m + j] 访问第 i 行,第 j 列的元素。 • 释放时,统一用 free(a) • 注意到:动态的数组,因为编译器光从指针没办法推断出列数 m ,因此要手动扁平化。 C++ 动态数组 • 0 码力 | 147 页 | 18.88 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 14 C++ 标准库系列课 - 你所不知道的 set 容器中插入元素 • 可以通过调用 insert 往 set 中添加一个元素。 • 用户无需关心插入的位置, 例如插入元素 3 时, set 会 自动插入到 2 和 4 之间, 从而使元素总是从小到大排 列。 • pairinsert(int val); 向 set 中插入元素 • 刚刚说过 set 具有自动去重 的功能,如果插入的元素已 经在 set 中存在,则不会完 一样。虽然你可能注意到这 里的刚好和插入的顺序相反 ?巧合而已,具体怎么顺序 是和 glibc 实现有关的。 • set 基于红黑树实现,相当 于二分查找 树, unordered_set 基于散 列哈希表实现,正是哈希函 数导致了随机的顺序。 不同版本的 set 容器比较 类型 去重 有序 查找 插入 vector × × O(n) O(1) ~ O(n) set √ √ O(logn) 0 码力 | 83 页 | 10.23 MB | 1 年前3
《深入浅出MFC》2/eDocument Template 的意義 / 430 Scribble 的 Document/View 設計 / 436 主視窗的誕生 / 438 工具列和狀態列的誕生(Toolbar & Status bar) / 440 滑鼠拖放(Drag and Drop) / 442 訊息映射(Message Map) / 445 羅塞達碑石:AfxSig_xx 的秘密 / 580 Scribble Step2:UI 物件的變化 / 585 改變選單 / 585 改變工具列 / 588 利用 ClassWizard 連接命令項識別碼與命令處理函式 / 590 維護 UI 物件狀態(UPDATE_COMMAND_UI) / ,本书 第5章有不少介绍。基本上它可以说是一个更有凝聚力,关联性更强的类别库。并不是 每一套C++ 类别库都有资格称为Application Framework,不过MFC 和OWL 都可入 列,IBM 的Open Class Library 也是。Application Framework 当然不一定得是C++ 类别 库,Java 和Delphi 应该也都称得上。 为使全书文字流畅精简,我用了一些缩写字:0 码力 | 1009 页 | 11.08 MB | 1 年前3
Hello 算法 1.1.0 C++ 版在计算机世界中,哈希表如同一位聪慧的图书管理员。 他知道如何计算索书号,从而可以快速找到目标图书。 第 6 章 哈希表 hello‑algo.com 115 6.1 哈希表 哈希表(hash table),又称散列表,它通过建立键 key 与值 value 之间的映射,实现高效的元素查询。具体而 言,我们向哈希表中输入一个键 key ,则可以在 ?(1) 时间内获取对应的值 value 。 如图 6‑1 所示,给定 std:hash() 仅提供基本数据类型的哈希值计算 // 数组、对象的哈希值计算需要自行实现 在许多编程语言中,只有不可变对象才可作为哈希表的 key 。假如我们将列表(动态数组)作为 key ,当列 表的内容发生变化时,它的哈希值也随之改变,我们就无法在哈希表中查询到原先的 value 了。 虽然自定义对象(比如链表节点)的成员变量是可变的,但它是可哈希的。这是因为对象的哈希值通常是基 于 完美二叉树是一个特例,在二叉树的中间层通常存在许多 None 。由于层序遍历序列并不包含这些 None ,因 此我们无法仅凭该序列来推测 None 的数量和分布位置。这意味着存在多种二叉树结构都符合该层序遍历序 列。 如图 7‑13 所示,给定一棵非完美二叉树,上述数组表示方法已经失效。 第 7 章 树 hello‑algo.com 149 图 7‑13 层序遍历序列对应多种二叉树可能性 为了解决此问题0 码力 | 379 页 | 18.47 MB | 1 年前3
Hello 算法 1.0.0 C++版在计算机世界中,哈希表如同一位聪慧的图书管理员。 他知道如何计算索书号,从而可以快速找到目标图书。 第 6 章 哈希表 hello‑algo.com 115 6.1 哈希表 「哈希表 hash table」,又称「散列表」,它通过建立键 key 与值 value 之间的映射,实现高效的元素查询。具 体而言,我们向哈希表中输入一个键 key ,则可以在 ?(1) 时间内获取对应的值 value 。 如图 6‑1 std:hash() 仅提供基本数据类型的哈希值计算 // 数组、对象的哈希值计算需要自行实现 在许多编程语言中,只有不可变对象才可作为哈希表的 key 。假如我们将列表(动态数组)作为 key ,当列 表的内容发生变化时,它的哈希值也随之改变,我们就无法在哈希表中查询到原先的 value 了。 虽然自定义对象(比如链表节点)的成员变量是可变的,但它是可哈希的。这是因为对象的哈希值通常是基 于 完美二叉树是一个特例,在二叉树的中间层通常存在许多 None 。由于层序遍历序列并不包含这些 None ,因 此我们无法仅凭该序列来推测 None 的数量和分布位置。这意味着存在多种二叉树结构都符合该层序遍历序 列。 如图 7‑13 所示,给定一棵非完美二叉树,上述数组表示方法已经失效。 第 7 章 树 hello‑algo.com 149 图 7‑13 层序遍历序列对应多种二叉树可能性 为了解决此问题0 码力 | 378 页 | 17.59 MB | 1 年前3
Hello 算法 1.0.0b5 C++版在计算机世界中,哈希表如同一位智能的图书管理员。 他知道如何计算索书号,从而可以快速找到目标书籍。 第 6 章 哈希表 hello‑algo.com 110 6.1 哈希表 「哈希表 hash table」,又称「散列表」,其通过建立键 key 与值 value 之间的映射,实现高效的元素查询。具 体而言,我们向哈希表输入一个键 key ,则可以在 ?(1) 时间内获取对应的值 value 。 如图 6‑1 所示,给定 std:hash() 仅提供基本数据类型的哈希值计算 // 数组、对象的哈希值计算需要自行实现 在许多编程语言中,只有不可变对象才可作为哈希表的 key 。假如我们将列表(动态数组)作为 key ,当列 表的内容发生变化时,它的哈希值也随之改变,我们就无法在哈希表中查询到原先的 value 了。 虽然自定义对象(比如链表节点)的成员变量是可变的,但它是可哈希的。这是因为对象的哈希值通常是基 于 二叉树可以用数组表示,方法是将节点值和空位按层序遍历顺序排列,并根据父节点与子节点之间的 索引映射关系来实现指针。 ‧ 二叉树的层序遍历是一种广度优先搜索方法,它体现了“一圈一圈向外”的分层遍历方式,通常通过队 列来实现。 ‧ 前序、中序、后序遍历皆属于深度优先搜索,它们体现了“走到尽头,再回头继续”的回溯遍历方式, 通常使用递归来实现。 ‧ 二叉搜索树是一种高效的元素查找数据结构,其查找、插入和删除操作的时间复杂度均为0 码力 | 377 页 | 30.69 MB | 1 年前3
共 15 条
- 1
- 2













