数据结构与算法(五)--- 哈希表、树、二叉树的入门

本文介绍了哈希表的定义、拉链法处理冲突,包括JDK1.8前后的实现方式;详细讲解了树的概念,如结点度、层次和深度;并探讨了二叉树的定义、存储结构以及遍历方法。
摘要由CSDN通过智能技术生成

一、哈希表

(一)哈希表的定义

哈希表(Hash table,也叫散列表) 是根据关键码值(Key value)而直接进行访问的数据结构,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
关键码值(Key value)也可以当成是key的hash值
这个映射函数叫做散列函数
存放记录的数组叫做散列表

数组,链表,哈希表的区别:

  • 数组(顺序表):寻址容易,只要使用下标即可;插入和删除难,会有大量的元素进行移动
  • 链表:插入与删除容易,但是查询难
  • 哈希表:寻址容易,插入删除也容易,综合了数组和链表的特性。

(二)哈希表的图解

Key : {14, 19, 5, 7, 21, 1, 13, 0, 18} 散列表: 大小为13 的数组 a[13]; 散列函数: f(x) = x mod 13; 遇到hash冲突则hash值+1(直到加到没有hash冲突的位置,此处先用简单的方式来解决hash冲突)

  • 散列表的大小:是需要根据自己的需求而定的
  • 散列函数:为了key计算后的结果hash值,能够不超出定义的散列表的大小
  • hash冲突:不同的key通过散列函数计算的hash值一样。自定义的哈希表需要设计好hash冲突解决的方法。
  • 装填因子:放入散列表中的数据个数 / 散列表的大小
    [1] 假设装填因子=0.7,散列表中的数据个数 / 散列表的大小 = 9/13 = 0.7,如果散列表中数据个数达到了9个,就需要对散列表进行扩容,扩容后再存放新的数据。HashMap设置的装填因子是0.75。
    [2] 那么为什么不全部放满了再扩容呢,需要根据装填因子?因为数据越接近散列表的大小,产生冲突的可能会越来越大
  • 缺点:扩容需要消耗大量的空间和性能。
    扩容会导致散列函数重新变化,[ 比如扩容后大小为50,那么f(x) = x mod 50 ],原本存入哈希表的key值都需要重新计算。
    HashMap的扩容就是2的n次方计算的。
  • 应用:散列表应用场景,是在数组大小变化的可能性不大的情况下:电话号码,字典,点歌系统,QQ,微信的好友等。
    比如系统的电话号码存放有上限值的,这样增删改查就能保持性能最快的一种方式。

在这里插入图片描述

(三)哈希表的拉链法

要能够手写一套性能优异的哈希表,需要了解所有的树结构。不同的语言,设计的哈希表也是有些差异的,HashMap就是采用了拉链法。

1、JDK1.8以前:数组 + 链表

优点:

  • 查找快:时间复杂度 O(n) ,( O(n/线性表的size) ) ,是一个线性的查找
    [e.g.] f(337) = 1,查找到数组角标1,然后再单链表查询到337。
  • 插入快:查找到数组角标,单链表的插入
  • 删除快:查找到数组角标,单链表的删除


缺点:

  • 大数据时代,如果数组容量不是很大,很有可能出现某一行链表个数超过几万几十万。(解决方法见数组 + 链表 + 红黑树)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值