Skip to content

Commit

Permalink
Chapter 14 section 07 completed.
Browse files Browse the repository at this point in the history
  • Loading branch information
liuyubobobo committed Jun 20, 2018
1 parent 56b1535 commit 0990590
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 25 deletions.
@@ -1,41 +1,48 @@
import java.util.Map;
import java.util.TreeMap;

public class HashTable<K, V> {
public class HashTable<K extends Comparable<K>, V> {

private final int[] capacity
= {53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741};

private static final int upperTol = 10;
private static final int lowerTol = 2;
private static final int initCapacity = 7;
private int capacityIndex = 0;

private TreeMap<K, V>[] hashtable;
private int size;
private int M;

public HashTable(int M){
this.M = M;
public HashTable(){
this.M = capacity[capacityIndex];
size = 0;
hashtable = new TreeMap[M];
for(int i = 0 ; i < M ; i ++)
hashtable[i] = new TreeMap<>();
}

public HashTable(){
this(initCapacity);
}

private int hash(K key){
return (key.hashCode() & 0x7fffffff) % M;
}

public int getSize(){
return size;
}

public void add(K key, V value){
TreeMap<K, V> map = hashtable[hash(key)];
// if(!hashtable[hash(key)].containsKey(key)){
if(!map.containsKey(key)){
if(map.containsKey(key))
map.put(key, value);
else{
map.put(key, value);
size ++;

if(size >= upperTol * M)
resize(2 * M);
if(size >= upperTol * M && capacityIndex + 1 < capacity.length){
capacityIndex ++;
resize(capacity[capacityIndex]);
}
}
}

Expand All @@ -46,8 +53,10 @@ public V remove(K key){
ret = map.remove(key);
size --;

if(size <= lowerTol * M && M > initCapacity)
resize(M / 2);
if(size < lowerTol * M && capacityIndex - 1 >= 0){
capacityIndex --;
resize(capacity[capacityIndex]);
}
}
return ret;
}
Expand All @@ -73,11 +82,14 @@ private void resize(int newM){
for(int i = 0 ; i < newM ; i ++)
newHashTable[i] = new TreeMap<>();

for(int i = 0 ; i < M ; i ++)
for(K key: hashtable[i].keySet())
newHashTable[hash(key)].put(key, hashtable[i].get(key));

int oldM = M;
this.M = newM;
for(int i = 0 ; i < oldM ; i ++){
TreeMap<K, V> map = hashtable[i];
for(K key: map.keySet())
newHashTable[hash(key)].put(key, map.get(key));
}

this.hashtable = newHashTable;
}
}
}
Expand Up @@ -58,7 +58,7 @@ public static void main(String[] args) {
RBTree<String, Integer> rbt = new RBTree<>();
for (String word : words) {
if (rbt.contains(word))
rbt.set(word, avl.get(word) + 1);
rbt.set(word, rbt.get(word) + 1);
else
rbt.add(word, 1);
}
Expand Down
132 changes: 132 additions & 0 deletions 14-Hash-Table/07-More-About-Resizing-in-Hash-Table/src/Solution.java
@@ -0,0 +1,132 @@
/// Leetcode 350. Intersection of Two Arrays II
/// https://leetcode.com/problems/intersection-of-two-arrays-ii/description/
///
/// 课程中在这里暂时没有介绍这个问题
/// 该代码主要用于使用Leetcode上的问题测试我们的HashTable类

import java.util.TreeMap;
import java.util.ArrayList;

public class Solution {

private class HashTable<K extends Comparable<K>, V> {

private final int[] capacity
= {53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741};

private static final int upperTol = 10;
private static final int lowerTol = 2;
private int capacityIndex = 0;

private TreeMap<K, V>[] hashtable;
private int size;
private int M;

public HashTable(){
this.M = capacity[capacityIndex];
size = 0;
hashtable = new TreeMap[M];
for(int i = 0 ; i < M ; i ++)
hashtable[i] = new TreeMap<>();
}

private int hash(K key){
return (key.hashCode() & 0x7fffffff) % M;
}

public int getSize(){
return size;
}

public void add(K key, V value){
TreeMap<K, V> map = hashtable[hash(key)];
if(map.containsKey(key))
map.put(key, value);
else{
map.put(key, value);
size ++;

if(size >= upperTol * M && capacityIndex + 1 < capacity.length){
capacityIndex ++;
resize(capacity[capacityIndex]);
}
}
}

public V remove(K key){
V ret = null;
TreeMap<K, V> map = hashtable[hash(key)];
if(map.containsKey(key)){
ret = map.remove(key);
size --;

if(size < lowerTol * M && capacityIndex - 1 >= 0){
capacityIndex --;
resize(capacity[capacityIndex]);
}
}
return ret;
}

public void set(K key, V value){
TreeMap<K, V> map = hashtable[hash(key)];
if(!map.containsKey(key))
throw new IllegalArgumentException(key + " doesn't exist!");

map.put(key, value);
}

public boolean contains(K key){
return hashtable[hash(key)].containsKey(key);
}

public V get(K key){
return hashtable[hash(key)].get(key);
}

private void resize(int newM){
TreeMap<K, V>[] newHashTable = new TreeMap[newM];
for(int i = 0 ; i < newM ; i ++)
newHashTable[i] = new TreeMap<>();

int oldM = M;
this.M = newM;
for(int i = 0 ; i < oldM ; i ++){
TreeMap<K, V> map = hashtable[i];
for(K key: map.keySet())
newHashTable[hash(key)].put(key, map.get(key));
}

this.hashtable = newHashTable;
}
}

public int[] intersect(int[] nums1, int[] nums2) {

HashTable<Integer, Integer> map = new HashTable<>();
for(int num: nums1){
if(!map.contains(num))
map.add(num, 1);
else
map.set(num, map.get(num) + 1);
}

ArrayList<Integer> res = new ArrayList<>();
for(int num: nums2){
if(map.contains(num)){
res.add(num);
map.set(num, map.get(num) - 1);
if(map.get(num) == 0)
map.remove(num);
}
}

int[] ret = new int[res.size()];
for(int i = 0 ; i < res.size() ; i ++)
ret[i] = res.get(i);

return ret;
}
}
17 changes: 13 additions & 4 deletions README.md
Expand Up @@ -175,6 +175,7 @@
| 10-5 Trie字典树和简单的模式匹配 | [Java](10-Trie/05-Trie-and-Pattern-Match/src/) |
| 10-6 Trie字典树和字符串映射 | [Java](10-Trie/06-Trie-and-Map/src/) |
| 10-7 更多和Trie字典树相关的话题 | [无代码] |
| 10-8 [文字补充] 基于哈希表或者数组的Trie | [无代码] |
| 补充代码1: 使用HashMap或者Array的Trie | [Java](10-Trie/Optional-01-Trie-Using-HashMap-and-Array/src/) |
| 补充代码2: TrieSet和TrieMap | [整理中,敬请期待] |
| 补充代码3: Trie的递归实现 | [整理中,敬请期待] |
Expand Down Expand Up @@ -212,6 +213,7 @@
| 13-7 红黑树中添加新元素 | [Java](13-Red-Black-Tree/07-Adding-Elements-in-Red-Black-Tree/src/) |
| 13-8 红黑树的性能测试 | [Java](13-Red-Black-Tree/08-The-Performance-of-Red-Black-Tree/src/) |
| 13-9 更多红黑树相关的话题 | [无代码] |
| 13-10 [文字补充] 红黑树任何不平衡都可以在三次旋转内解决? | [无代码] |
| 补充代码1: 红黑树中的删除最大元素 | [整理中,敬请期待] |
| 补充代码2: 红黑树中的删除最小元素 | [整理中,敬请期待] |
| 补充代码3: 红黑树中的删除任意元素 | [整理中,敬请期待] |
Expand All @@ -229,12 +231,19 @@
| 14-6 哈希表的动态空间处理与复杂度分析 | [Java](14-Hash-Table/06-Resizing-in-Hash-Table/src/) |
| 14-7 哈希表更复杂的动态空间处理方法 | [Java](14-Hash-Table/07-More-About-Resizing-in-Hash-Table/src/) |
| 14-8 更多哈希冲突的处理方法 | [无代码] |
| 补充代码1: 基于哈希表的映射和集合 | [整理中,敬请期待] |
| 补充代码2: 开放地址法解决哈希冲突 | [整理中,敬请期待] |
| 补充代码1: 每个地址存储链表的哈希表 | [整理中,敬请期待] |
| 补充代码2: 每个地址可以从链表转换到红黑树的哈希表 | [整理中,敬请期待] |
| 补充代码3: 基于哈希表的无序映射和无序集合 | [整理中,敬请期待] |
| 补充代码4: 开放地址线性探测解决哈希冲突 | [整理中,敬请期待] |
| 补充代码5: 开放地址二次探测解决哈希冲突 | [整理中,敬请期待] |
| 补充代码6: 开放地址双重哈希解决哈希冲突 | [整理中,敬请期待] |
| 补充代码7: 再哈希法解决哈希冲突 | [整理中,敬请期待] |
| 补充代码8: Coalesced Hashing | [整理中,敬请期待] |
| **第十五章 结语** | [无代码] |
| 15-1 更多数据结构和相关练习,大家加油! | [无代码] |
| 15-1 更广阔的数据结构的世界,大家加油! | [无代码] |
| 15-2 [文字补充]更多数据结构的练习:) | [无代码] |
| **第十六章 补充章节:B类树** | [更新中,敬请期待] |
| | |
| [由于B类树不是课程最初规划内容] | [更新时间待定,敬请期待] |

课程正在更新中,敬请期待:)

Expand Down

0 comments on commit 0990590

Please sign in to comment.