算法学习笔记----散列表

news/2024/7/4 1:39:28

1.散列函数

 散列函数:无论你给它什么数据,它都还你一个数字。


散列函数 将输入映射到数字。你可能认为散列函数输出的数字没什么规律,但其实散列函数必须满足一些要求。

1、它必须是一致的。例如,假如你输入apple时得到的是4,那么每次输入apple时,得到的都必须为4.如果不是这样,散列表将毫无用处。

2、它应将不同的输入映射到不同的数字。例如,如果一个散列函数无论输入什么都返回1,它就不是好的散列函数。最理想的情况是,将输入的映射到不同的数字。

 

散列函数准确的指出了数字的存储位置,你根本不用查找!之所以能够这样,具体原因如下。

1、散列函数总是将同样的输入到相同的索引。每次你输入acocado,得到的都是同一个数字。因此,你可首先使用它来确定将鳄梨的价格存储在什么地方,并在以后使用它来确定鳄梨的价格存储在什么地方。

2、散列函数将不同的输入映射到不同的索引。acocado映射到索引4,milk映射到索引0,每种商品都映射到数组的不同位置,让你能够将其价格存储到这里。

3、散列函数知道数组有多大,只返回有效的索引。如果数组包含5个元素,散列函数就不会返回无效索引100。

散列表也被称为散列映射,映射,字典和关联数组。散列表的速度很快!你可以立即获取数组中的元素,而散列表也是用数组来存储数据,因此获取元素的速度和数组一样快。

散列表 = 哈希表

js 实现哈希表

const m = new Map();

const ma = new Map([
    ['name', 'zhangsan'],
    ['age', 10]
]);
ma.size // 2
ma.has('name') // true
ma.get('name') // "张三"


let map = new Map();
map.set(-0, 123);
map.get(+0) // 123

map.set(true, 1);
map.set('true', 2);
map.get(true) // 1

map.set(undefined, 3);
map.set(null, 4);
map.get(undefined) // 3

map.set(NaN, 123);
map.get(NaN) // 123

集合中的键和值可以是任何类型。如果使用现有密钥向集合添加值,则新值会替换旧值。

1. 使用的是 Map,Map 更类似于 HashMap 而不是 Hashset
2. 广义来说,判断 对象是否存在在 HashMap 中的均摊时间复杂度为 O(1),

狭义来说,不同的编程语言实现 HashMap 的方式都不同,但是 Javascript 的 Map 对象非常类似哈希表,所以也是 O(1)

 

案例

模拟一个电话表 并查询姓名是否重复

let voted = new Map();
voted.set('王二',18866669999)
if(voted.has('王二')){
	console.log('已经有了')
}else{
	voted.set('王二',18866669999)
}

 

散列表适用于:

模拟映射关系;

防止重复

缓存/记住数据,以免服务器在通过处理来生成它们。

 

冲突 

散列函数总是将不同的键映射到数组的不同位置。实际上几乎不可能编写出这样的散列函数。

这里的经验教训有两个。

散列函数很重要。前面的散列函数将所有的键都映射到一个位置,而最理想的情况是,算列函数将键均匀的映射到散列表的不同位置。

如果散列表存储的链表很长,散列表的速度将急剧下降。然而,如果使用的散列函数很好,这些链表就不会很长!

性能

在平均的情况下,散列表执行各种操作的时间都为O(1),O(1)被称为常量时间。

 

简单查找的运行时间为线性时间。  O(n) -------线性时间

二分查找的速度更快,所需的时间为 对数时间。  O(log n) -------对数时间

在散列表中查找所花费的时间为常量时间。  O(1)-----------常量时间

但是 在最糟糕的情况下,散列表的各种操作的速度都很慢,因此,在使用散列表时,避开最糟糕情况至关重要。为此,需要避免冲突。而要避免冲突,需要有:

  较低的填装因子;

  良好的散列函数。

 

本章小结

散列表是一种功能强大的数据结构,其操作速度快,还能让你以不同的方式简历数据模型。你可能很快会发现自己经常在使用它。

1、你可以结合散列函数和数组来创建散列表。

2、冲突很糟糕,你应使用可以最大限度减少冲突的散列函数。

3、散列表的查找、插入和删除速度都非常的快。

4、散列表适合用于模拟映射关系

5、一旦填装因子超过0.7,就该调整算列表的长度。

6、散列表可用于缓存数据,例如在web服务器上。

7、散列表非常适合用于防止重复。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


http://www.niftyadmin.cn/n/3655854.html

相关文章

JavaScript -------- 数组1

一、创建数组 通过 [] 操作符声明一个数组变量: var numbers [ ] 得到一个长度为0的空数组。 可以通过内建的length属性 console.log(numbers.length) // 0 在声明数组变量时,直接在 [ ] 操作符中放入一组元素; var numbers [1,…

.Net Micro Framework研究—Shapes命名空间

试验平台:.Net Micro Framework 模拟器在Microsoft.SPOT.Presentation.Shapes命名空间下,包含几个形状对象,主要有Ellipse、Line、Polygon、Rectangle,同样也只有Rectangle实现的最好,其他形状都不支持填充色&#xff…

JavaScript -------- 数组2

迭代器方法 这些方法对数组中的每个元素应用一个函数, 可以返回一个值、 一组值或者一个新数组。 1 不生成新数组的迭代器方法 forEach(), 该方法接受一个函数作为参数, 对数组中的每个元素使用该函数。 function square(num) { …

.Net Micro Framework研究—中文显示

试验平台:.Net Micro Framework 模拟器微软示例程序中,仅支持两种字体(small.tinyfnt和NinaB.tinyfnt),并不支持中文。翁祖泉老师在《如何在Microsoft .NET Micro Framework 的应用程序中添加中文字体?》的…

JavaScript --- 数组练习题

1. 创建一个记录学生成绩的对象, 提供一个添加成绩的方法, 以及一个显示学生平均成绩的方法。 function Warehouse() {this.formData []; // 学生成绩库this.add add; // 添加方法this.average average; // 计算平均值}function add(arr) {this…

javascript------列表

一、 列表的抽象数据类型定义 列表是一组有序的数据。每个列表中的数据称之为元素。在JavaScript中,列表中的元素可以是任意数据类型。列表中可以保存多少元素并没有事先限定,实际使用时元素的数量受到程序内存的限制。 属性 listSize 列表的…

.Net Micro Framework研究—模拟器改造

试验平台:.Net Micro Framework 模拟器由于Digi提供的开发板没有LCD显示屏,所以有关绘图方面的操作,只好在模拟器上进行了。如果大家参加了9月18日在北京召开的.Net Micro Framework2007技术大会,并且耐心等到最后,大会…