Skip to content

Commit b634094

Browse files
committed
二叉树 练习和hash 基础知识
1 parent dcd790b commit b634094

2 files changed

Lines changed: 95 additions & 2 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package algorithm.basic04;
2+
3+
/**
4+
* @Created by mood321
5+
* @Date 2019/11/5 0005
6+
* @Description TODO
7+
*/
8+
public class Code_08_CompleteTreeNodeNumber {
9+
public static class Node{
10+
int data;
11+
Node left;
12+
Node right;
13+
public Node(int data){
14+
this.data=data;
15+
}
16+
}
17+
public static int nodeNum(Node head) {
18+
if(head==null){
19+
return 0;
20+
}
21+
return bs(head,1,mostLealLeft(head,1));
22+
}
23+
24+
private static int bs(Node head, int leavl, int h) {
25+
if(leavl == h){
26+
return 1;
27+
}
28+
if(h == mostLealLeft(head.right, leavl +1)){
29+
return (1<< (h-leavl)) +bs(head.right, leavl +1, h); // << 运算等级 很低
30+
}else {
31+
return (1<<(h -leavl -1)) +bs(head.left,leavl+1,h);
32+
33+
}
34+
}
35+
36+
private static int mostLealLeft(Node head, int leal) {
37+
while(head!=null){
38+
leal++;
39+
head=head.left;
40+
}
41+
return leal-1;
42+
43+
}
44+
public static void main(String[] args) {
45+
Node head = new Node(1);
46+
head.left = new Node(2);
47+
head.right = new Node(3);
48+
head.left.left = new Node(4);
49+
head.left.right = new Node(5);
50+
head.right.left = new Node(6);
51+
System.out.println(nodeNum(head));
52+
53+
}
54+
}

src/main/resources/note/Algorithm/算法学习基本数据结构和算法原型.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,44 @@
7272
<p>1. 有右子节点 无左子树 一定不是
7373
<p>2. 有左子树 无右子树 接下来所有节点必须是叶子节点 才是完全二叉树
7474
<p> 注: 深度遍历用栈 广度用队列
75-
76-
###
75+
+ 8 已知一棵完全二叉树,求其节点的个数
76+
<p>要求:时间复杂度低于O(N),N为这棵树的节点个数
77+
<p> 思路:1. 直接遍历 时间复杂度时O(n)
78+
<p> 2. 满二叉树的节点个数是= (1<< 高度)-1 能把一个二叉树 拆分成左子树 和右子树,
79+
<p> 在右子树的最左节点存在时 左子树一定是一个满二叉树 ,当最左节点高度比左子树小 右子树一定是一个 高度减1的满二叉树 O(Log N)^2
80+
<p> <a href="https://github.com/mood321/JavaDemo/blob/master/src/main/java/algorithm/basic04/Code_08_CompleteTreeNodeNumber.java">code</a>
81+
82+
### Hash 算法和散列表
83+
#### Hash 算法
84+
<p> Hash码 --由Hash算法(MD5、SHA 等) 计算出来的十六进制的数字
85+
86+
##### 经典Hash函数性质:
87+
<p>1. 输入域是无穷大的
88+
<p>2. 输出是有范围的
89+
<p>3. 在输入一样时 输出是一样的
90+
<p>4. 在输入不一样是,输出也有可能一样(就是hash碰撞 1,2,3 会导致hash碰撞)
91+
<p>5. 在大量输入的时候,得到的相对应的值是均匀分布在 输出范围内的 叫离散型( 在实际应用中很重要的特性,如负载均衡,分片)
92+
93+
##### Hash函数特性:
94+
<p>1. 输入和输出是没有关系的
95+
<p>2. 因为在输出域上均匀分布,得到推论: 一组数据得到的Hash码%m,在0~m-1上也是均匀分布的
96+
<p>3.Hash 码的每一位是相对独立的 彼此关系不大
97+
98+
##### 应用
99+
<p>1.安全加密
100+
<p>2.唯一标识
101+
<p>3.数据校验
102+
<p>4.散列函数
103+
<p>5.负载均衡
104+
<p>6.数据分片
105+
<p>7.分布式存储
106+
107+
#### Hash 表
108+
##### 经典Hash表实现 (java 实现在8中加入了红黑树)
109+
<p>1. 生成数组 得到大小len
110+
<p>2. put 时获取key的hashcode 然后 %len 得到他属于数组的位置
111+
<p>3. 数组里面存链表,检查对应位置 下是否有当前key的节点,有更新,无,链在链表后面
112+
<p>4. 如果链表长度到达 阈值,因为hash算法的特性 均匀分布,所以数组其他其他位置类似,此时扩容
113+
<p>5. 扩容 重新调整数组大小,从新hash,分配(在java中 扩容是<<1 所以实际只有一半需要从新分配 具体可以看HashMap的笔记)
114+
<p> 离线扩容: 在离线时扩容, 扩容完成替换
115+

0 commit comments

Comments
 (0)