查找算法小结

项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步

前言

对数据进行查找是数据处理中一个最基本最常见同时也最重要的操作。那么常见的查找方法有哪些,怎么能够实现又好又快的查找方式呢?下面来做一个小结

1.遍历,顺序查找

如果数据没有任何特点可言,要在一堆数据比如一个一维数组中查找一个特定的数据,此一维数组没有规律。那么很自然想到的方法就是遍历该一维数组,然后与特定数据进行比较看是否相同。

时间复杂度分析
该特定数据有可能再数组开头,也有可能再数组的末尾,那么遍历数组的话最少需要1次,最多需要n次,平均则为(1+n)/2次,所以时间复杂度为O(n)。

2.二分查找

上面的顺序查找当然是最简单粗暴也是效率最低的一种方式,其本质原因是数组没有任何特点,数据杂乱无章,所以我们没有较好的办法进行优化。那如果原始数据排列比较有特点,我们是不是可以有更好的方式?
哈佛的计算机公开课视频中,主讲的老师一开场有个很生动的例子,就是给学生一本字典查某个特定的名字在字典中的哪一页。大家想想字典的数据有什么特点?字典的数据,是按照字母序升序排列的。所以如果去查找一个人名字的时候,我们先翻到字典中间位置,如果此时该名字的字母序比字典中间位置的字母序大,那说明名字必出现在字典前半部分,那么我们去前半部分查,反之则去后半部分查。以此类推,一直到查到名字为止。
时间复杂度分析:
用二分查找时,最少需要查一次,最多需要log(n+1)次,平均时间复杂度为O(log(n)),比顺序查找的O(n)效率高很多
所以,二分查找的优点为效率高,缺点是要求原始数据有序。

3.Hash

hash又叫散列,他的原理是根据关键字的key值,通过hash算法将key值映射到表中的某一个位置得到value值,从而在查找的时候可以实现快速查找的目的。这个映射函数叫做散列函数,存放(key,value)对的数据结构则被称为散列表。

java中hash的典型实现有HashMap,关于HashMap的分析有很多,在这里不再阐述。稍微提一下的是,HashMap的冲突解决方式,在jdk1.8之前是使用的拉链法的形式,即如果不同的key映射到了同一个位置,后面会使用一个链表将这些key组织起来。从jdk1.8开始,当链表的长度超过阈值以后,链表会转换成红黑树。

时间复杂度分析
哈希表寻址容易,插入删除也相对容易。如果散列函数设计良好没有冲突,理论上可以达到O(1)的时间复杂度。
但是哈希表如果扩容,会耗费大量的空间与性能,同时散列函数可能也需要重新设计。另外,Hash表中的数据也是无序的。

所以综合上面的特点来看,如果预先能估算数据的大小,有足够的空间存储哈希表,且不要求数据有序,此时哈希表是个不错的选择。因为哈希表的查找,插入,删除都是O(1)复杂度(不考虑冲突)。

4.BST(Binary Search Tree)

排序二叉树与普通二叉树的区别在于:每一个节点记录一个数据,同时满足左分支的数据都小于右分支的数据。
从查找过程看,排序二叉树与二分查找相似,都是O(log(n))的时间复杂度。
为了维护排序二叉树的有序性,二叉排序树不需要挪动节点,只需要修改指针可以完成插入和删除的操作,平均耗时O(log(n))。而如果是线性表比如数组,需要的时间复杂度为O(n)。

所以当有序表是静态查找表时,适宜用顺序表如数组作为其存储结构,而采用二分查找实现其查找操作;若有序表是动态查找表,经常有增加与删除节点的操作,则可以选择排序二叉树作为其数据存储结构。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值