数据结构笔记

2-3树&红黑树

 

 

哈希表

哈希函数的设计

例如26个字符 new一个int[26]。可以用来做哈希

整型值

小范围正整数,直接使用正整数。

大整数 通常做法 取模  比如取后四位 mod 1000 模一个素数分布效果更好

如果对日期这种取模,只能在01-31,会造成分布不均匀。

要具体分析。

浮点型

32位或64位机器,浮点型会有特殊表示。

32位前8位

64位是前11位

使用整数的方式来解析

 

Java的hashCode

haseSet存数据,会先计算hashCode,有冲突则通过equals判断是否是同一个对象。

 

哈希冲突

链地址法

  • 数组,长度M
  • 元素对M取模
    • (hashCode(k1) & 0x7fffffff) % M
    • 前面是31位的0做与,去掉第一位的符号位。
  • 算完模后,例如4,索引为4的位置,就存上就好了。
  • 有冲突时
  • 在链表尾部加冲突的节点。
  •  也可以用平衡树存

扩容 hashMap 默认 数组长度*0.75  即 16*0.75=12 12个长度就扩容。

 

开放地址法

所有索引都有机会存不同的hash值。

正常先存储,遇到hash冲突,就把冲突的元素,向后去找空的空间。

比如对10取hash值。

占满了,就会一直探测。

改进:

平方探测法

每次向下找平方,不是+1

二次hash法

 

对于开放地址法,扩容合适,也是O(1)复杂度

再Hash法 Rehashing

Coalesced Hashing

结合seperate Chaining 和 Open Addressing

 

 

SQRT O(sqrt(n)) 根号N时间复杂度

代码实现更方便,虽然时间复杂度会比线段树O(logn)高一些。

分块分组的思想,解决区间问题。

 

 

 

 链表

class Node{

  E e;

  Node next;

}

不能随机从一个索引拿出元素,next连接的。

数组在尾部添加方便;链表在头部head添加方便。

数据量大的时候,链表更损耗性能,因为每个节点都要New,而数组虽然resize,但是每次都是翻倍的,对内存的消耗会小。

 

那么链表和数组的核心区别是什么?答案是:链表是一种动态的数据结构。

什么叫动态的数据结构?就是我需要存多少数据,就去 new 多少空间。而不像数组,我们需要一次性 new 够所有需要的空间。这就产生了空间的浪费。虽然课程中我们之前介绍的“动态数组”也有动态两个字,但其实只是把这个一次性 new 很多空间的操作隐藏了而已,其内部本质依然是静态数组,依然会有空间的浪费。依然会有存了 101 个数据,但是有 200 个空间的问题。

动态数据结构是非常重要的一个概念。单纯从链表的角度看,或许“动态”的意义还不明显,但是等学到树结构,你就会看到,“动态”的意义是巨大的。

 

链表与递归

树和递归比较方便,链表也是可以。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

todo

 

posted @ 2023-08-28 21:34  CodingOneTheWay  阅读(18)  评论(0编辑  收藏  举报
回到顶部