当前位置: 代码迷 >> 综合 >> Data Structure (三)
  详细解决方案

Data Structure (三)

热度:94   发布时间:2023-11-29 14:43:36.0

动态规划

1.区间调度问题

1.1无权区间调度问题

?任务j开始于sj,结束于fj

?如果两个任务没有重叠的时间,则两个任务互相兼容
?目标:找到最多/最大互相兼容的任务集合

贪心算法总是做出当前最优的选择。贪心算法并不总能得到最优解,但是它是最简单最容易实现的算法。

无权区间调度问题贪心算法:先将任务以某种顺序排序,再按顺序挑选互相兼容的任务。

按照结束时间排序

??????小白带你学---贪心算法(Greedy Algorithm) - 知乎 (zhihu.com)

1.2带权区间调度问题

找到权重最大且互相兼容的任务集合

动态规划

a.确定状态
b.  状态转移方程
c.  初始条件和边界情况
d. 确定计算顺序

分治

(39条消息) 算法与数据结构_Hi丶ImViper的博客-CSDN博客

高度平衡二叉树是一棵满足每个节点的左右两个子树的高度差的绝对值不超过1的二叉树。

(39条消息) 二叉树合集(六):高度平衡的二叉搜索树简介(图文解析)_Hi丶ImViper的博客-CSDN博客_高度平衡的二叉树搜索树

将有序数组转换为二叉搜索树

 从中序与后序遍历序列构造二叉树

哈希表

也叫做散列表。是根据关键字和值(Key Value)直接进行访问的数据结构。也就是说,它通过关键字 key 和一个映射函数 Hash(key) 计算出对应的值 value,然后把键值对映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做 哈希函数(散列函数),用于存放记录的数组叫做哈希表(散列表)。

?向哈希表中插入一个关键字:哈希函数决定该关键字的对应值应该存放到表中的哪个区块,并将对应值存放到该区块中。
?在哈希表中搜索一个关键字:使用相同的哈希函数从哈希表中查找对应的区块,并在特定的区块搜索该关键字对应的值。

哈希表在生活中的应用也很广泛,其中一个常见例子就是「查字典」。

哈希函数:将哈希表中元素的关键键值映射为元素存储位置的函数。

?哈希函数应该易于计算,并且尽量使计算出来的索引值均匀分布。
?哈希函数计算得到的哈希值是一个固定长度的输出值。
?如果 Hash(key1) 不等于 Hash(key2),那么 key1、key2 一定不相等。
?如果 Hash(key1) 等于 Hash(key2),那么 key1、key2 可能相等,也可能不相等(会发生哈希碰
撞)。

通常用到的哈希函数方法有:直接定址法、除留余数法、平方取中法、基数转换法、数字分析法、折叠法、随机数法、乘积法、点积法等。

1.直接定址法

Hash(key) = key 或者 Hash(key) = a * key + b,其中 a 和 b 为常数。

2.除留余数法

假设哈希表的表长为 m,取一个不大于 m 但接近或等于 m 的质数 p,利用取模运算,
将关键字转换为哈希地址。即:Hash(key) = key % p,其中 p 为不大于 m 的质数。

3.平方取中法

先通过求关键字平方值的方式扩大相近数之间的差别,然后根据表长度取关键字平方值的
中间几位数为哈希地址。

比如:Hash(key) = (key * key) // 100 % 1000,先计算平方,去除末尾的 2 位数,再取中间 3 位
数作为哈希地址。

4.基数转换法

将关键字看成另一种进制的数再转换成原来进制的数,然后选其中几位作为哈希地址

哈希冲突

不同的关键字通过同一个哈希函数可能得到同一哈希地址,即 key1 ≠ key2,而 Hash(key1) = Hash(key2),这种现象称为哈希冲突。

常用的哈希冲突解决方法主要是两类:「开放地址法」和「链地址法」。

1.开放地址法

开放地址法:指的是将哈希表中的「空地址」向处理冲突开放。当哈希表未满时,处理冲突时需要尝试另外的单元,直到找到空的单元为止。
当发生冲突时,开放地址法按照下面的方法求得后继哈希地址:H(i) = (Hash(key) + F(i)) % m,i = 1, 2, 3, ..., n (n ≤ m - 1)。
?H(i) 是在处理冲突中得到的地址序列。即在第 1 次冲突(i = 1)时经过处理得到一个新地址 H(1),
如果在 H(1) 处仍然发生冲突(i = 2)时经过处理时得到另一个新地址 H(2) …… 如此下去,直到
求得的 H(n) 不再发生冲突。
?Hash(key) 是哈希函数,m 是哈希表表长,取余目的是为了使得到的下一个地址一定落在哈希表中。
?F(i) 是冲突解决方法,取法可以有以下几种:
?线性探测法:F(i) = 1, 2, 3, ..., m - 1。
?二次探测法:F(i) = 1^2, -1^2, 2^2, -2^2, ..., n^2(n ≤ m / 2)。
?伪随机数序列:F(i) = 伪随机数序列。

2.链地址法

将具有相同哈希地址的元素(或记录)存储在同一个线性链表中。

我们假设哈希函数产生的哈希地址区间为 [0, m - 1],哈希表的表长为 m。则可以将哈希表定义为一个有 m 个头节点组成的链表指针数组 T。
?这样在插入关键字的时候,我们只需要通过哈希函数 Hash(key) 计算出对应的哈希地址 i,然后将
其以链表节点的形式插入到以 T[i] 为头节点的单链表中。在链表中插入位置可以在表头或表尾,也
可以在中间。如果每次插入位置为表头,则插入操作的时间复杂度为 O(1)。
?而在在查询关键字的时候,我们只需要通过哈希函数 Hash(key) 计算出对应的哈希地址 i,然后将
对应位置上的链表整个扫描一遍,比较链表中每个链节点的键值与查询的键值是否一致。查询操作
的时间复杂度跟链表的长度 k 成正比,也就是 O(k)。对于哈希地址比较均匀的哈希函数来说,理论上讲,k = n // m,其中 n 为关键字的个数,m 为哈希表的表长。

 

 

  相关解决方案