数据结构:哈希表与有序表

215 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

哈希表

介绍

  • 哈希表在使用层面上可以理解为一种集合结构
  • 如果只有key,没有伴随数据value,可以使用HashSet结构(C++中叫UnOrderedSet)
  • 如果既有key,又有伴随数据value,可以使用HashMap结构(C++中叫UnOrderedMap)
  • 有无伴随数据,是HashSet和HashMap唯一的区别,底层的实际结构是一回事
  • 使用哈希表增(put)删(remove)改(put)查(get)的操作,可以认为时间复杂度为O(1),但是常数时间比较大
  • 放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小
  • 放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是这个东西内存地址的大小
  • 哈希表在使用时,认为其增删改查操作的时间复杂度为`常数。

有序表

介绍

  • 有序表在使用层面上可以理解为一种集合结构
  • 如果只有key,没有伴随数据value,可以使用TreeSet结构(C++中叫OrderedSet)
  • 如果既有key,又有伴随数据value,可以使用TreeMap结构(C++中叫OrderedMap)
  • 有无伴随数据,是TreeSet和TreeMap唯一的区别,底层的实际结构是一回事
  • 哈希表和有序表的区别是,有序表把key按照顺序组织起来,而哈希表完全不组织
  • 红黑树、AVL树、size-balance-tree和跳表等都属于有序表结构,只是底层具体实现不同
  • 不管是什么底层具体实现,只要是有序表,都有以下固定的基本功能和固定的时间复杂度

固定操作

  • void put(K key, V value):将一个(key,value)记录加入到表中,或者将key的记录更新层value
  • V get(K key):根据给定的key,查询value并返回
  • void remove(K key):移除key的记录
  • boolean containsKey(K key):询问是否有关于key的记录
  • K firstKey():返回所有键值的排序结果中,最左(最小)的那个
  • K lastKey():返回所有键值的排序结果中,最右(最大)的那个
  • K floorKey(K key):如果表中存入过key,返回key;否则返回所有键值的排序结果中,key的前一个
  • K ceilingKey(K key):如果表中存入过key,返回key;否则返回所有键值的排序结果中,key的后一个 以上所有操作时间复杂度都是O(logN),N为有序表含有的记录数

Javascript中的哈希表

Javascript中,哈希表是ES6中的Set和Map对象,另外还有WeakSet和WeakMap对象,两者区别是:Set和Map对于对象的引用属于强引用,而WeakSet和WeakMap属于弱引用。两者区别详情可以看另外一篇文章:ES6为何加入WeakSet、WeakMap