《算法》第三章部分程序 part 4
▶ 书中第三章部分程序,加上自己补充的代码,包括散列表、线性探查表
● 散列表
package package01; import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.SequentialSearchST;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut; public class class01<Key, Value>
{
private static final int INIT_CAPACITY = 4; // 默认构造函数参数
private int n; // 待插入元素数
private int m; // 散列表尺寸
private SequentialSearchST<Key, Value>[] st; // 散列表 public class01()
{
this(INIT_CAPACITY);
} public class01(int capacity)
{
m = capacity;
st = (SequentialSearchST<Key, Value>[]) new SequentialSearchST[m];
for (int i = 0; i < m; i++)
st[i] = new SequentialSearchST<Key, Value>();
} public int size()
{
return n;
} public boolean isEmpty()
{
return size() == 0;
} private void resize(int capacity)
{
class01<Key, Value> temp = new class01<Key, Value>(capacity);
for (int i = 0; i < m; i++)
{
for (Key key : st[i].keys())
temp.put(key, st[i].get(key));
}
m = temp.m;
n = temp.n;
st = temp.st;
} public boolean contains(Key key)
{
if (key == null)
throw new IllegalArgumentException("\n<contains> key == null.\n");
return get(key) != null;
} private int hash(Key key)
{
return (key.hashCode() & 0x7fffffff) % m;
} public Value get(Key key)
{
if (key == null)
throw new IllegalArgumentException("\n<get> key == null.\n");
return st[hash(key)].get(key);
} public void put(Key key, Value val)
{
if (key == null)
throw new IllegalArgumentException("\n<get> key == null.\n");
if (val == null)
{
delete(key);
return;
}
if (n >= 10 * m) // 平均链表长度不小于 10,扩容
resize(2 * m);
int i = hash(key);
if (!st[i].contains(key))
n++;
st[i].put(key, val);
} public void delete(Key key)
{
if (key == null)
throw new IllegalArgumentException("\n<delete> key == null.\n");
if (!contains(key))
return;
int i = hash(key);
if (st[i].contains(key))
n--;
st[i].delete(key);
if (m > INIT_CAPACITY && n <= 2 * m) // 平均链表长度小于 2,缩容
resize(m / 2);
} public Iterable<Key> keys()
{
Queue<Key> queue = new Queue<Key>();
for (int i = 0; i < m; i++)
{
for (Key key : st[i].keys())
queue.enqueue(key);
}
return queue;
} public static void main(String[] args)
{
class01<String, Integer> st = new class01<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++)
{
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.keys())
StdOut.println(s + " " + st.get(s));
}
}
● 线性探查表
package package01; import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut; public class class01<Key, Value>
{
private static final int INIT_CAPACITY = 4;
private int n;
private int m;
private Key[] keys;
private Value[] vals; public class01()
{
this(INIT_CAPACITY);
} public class01(int capacity)
{
m = capacity;
n = 0;
keys = (Key[]) new Object[m];
vals = (Value[]) new Object[m];
} public int size()
{
return n;
} public boolean isEmpty()
{
return size() == 0;
} private void resize(int capacity)
{
class01<Key, Value> temp = new class01<Key, Value>(capacity);
for (int i = 0; i < m; i++)
{
if (keys[i] != null)
temp.put(keys[i], vals[i]);
}
m = temp.m;
keys = temp.keys;
vals = temp.vals; } public boolean contains(Key key)
{
if (key == null)
throw new IllegalArgumentException("\n<contains> key == null.\n");
return get(key) != null;
} private int hash(Key key)
{
return (key.hashCode() & 0x7fffffff) % m;
} public Value get(Key key)
{
if (key == null)
throw new IllegalArgumentException("\n<get> key == null.\n");
for (int i = hash(key); keys[i] != null; i = (i + 1) % m) // 表荷载不会超过 1/2,所以不会绕圈
{
if (keys[i].equals(key))
return vals[i];
}
return null;
} public void put(Key key, Value val)
{
if (key == null)
throw new IllegalArgumentException("\n<get> key == null.\n");
if (val == null)
{
delete(key);
return;
}
if (n >= m / 2) // 荷载超过一半了,扩容
resize(2 * m);
int i;
for (i = hash(key); keys[i] != null; i = (i + 1) % m)
{
if (keys[i].equals(key))
{
vals[i] = val;
return;
}
}
keys[i] = key;
vals[i] = val;
n++;
} public void delete(Key key)
{
if (key == null)
throw new IllegalArgumentException("\n<delete> key == null.\n");
if (!contains(key))
return;
int i = hash(key);
for (; !key.equals(keys[i]); i = (i + 1) % m); // 找到目标元素
keys[i] = null; // 删除目标元素
vals[i] = null;
for (i = (i + 1) % m; keys[i] != null; i = (i + 1) % m) // 在下一个 null 之前,所有元素重新插入
{
Key keyToRehash = keys[i];
Value valToRehash = vals[i];
keys[i] = null;
vals[i] = null;
n--;
put(keyToRehash, valToRehash);
}
n--;
if (n > 0 && n <= m / 8) // 荷载小于 1/8, 缩容
resize(m / 2);
} public Iterable<Key> keys()
{
Queue<Key> queue = new Queue<Key>();
for (int i = 0; i < m; i++)
{
if (keys[i] != null)
queue.enqueue(keys[i]);
}
return queue;
}
private boolean check()
{
if (m < 2 * n) // 检查容量
{
System.err.println("\n<check> m < 2 * n.\n");
return false;
}
for (int i = 0; i < m; i++) // 检查 hash
{
if (keys[i] == null)
continue;
if (get(keys[i]) != vals[i])
{
System.err.println("\n<check> hash error at i = ", i, ", key[i] = ", get(keys[i]), ", val[i] = ", vals[i], ".\n");
return false;
}
}
return true;
} public static void main(String[] args)
{
class01<String, Integer> st = new class01<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++)
{
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.keys())
StdOut.println(s + " " + st.get(s));
}
}
《算法》第三章部分程序 part 4的更多相关文章
- 《算法》第三章部分程序 part 6
▶ 书中第三章部分程序,加上自己补充的代码,包含双向索引表.文建索引.稀疏向量类型 ● 双向索引表 package package01; import edu.princeton.cs.algs4.S ...
- 《算法》第三章部分程序 part 5
▶ 书中第三章部分程序,加上自己补充的代码,包含公共符号表.集合类型 ● 公共符号表,用于普通查找表的基本类 package package01; import java.util.NoSuchEle ...
- 《算法》第三章部分程序 part 3
▶ 书中第三章部分程序,加上自己补充的代码,红黑树 ● 红黑树,大部分方法与注释与二叉树相同 package package01; import java.util.NoSuchElementExce ...
- 《算法》第三章部分程序 part 2
▶ 书中第三章部分程序,加上自己补充的代码,平衡二叉搜索树 ● 平衡二叉搜索树 package package01; import java.util.NoSuchElementException; ...
- 《算法》第三章部分程序 part 1
▶ 书中第三章部分程序,加上自己补充的代码,包括单词频率统计,(单链表)顺序查找表,二分查找表 ● 单词频率统计 package package01; import edu.princeton.cs. ...
- 《算法》第二章部分程序 part 3
▶ 书中第二章部分程序,加上自己补充的代码,包括各种优化的快排 package package01; import edu.princeton.cs.algs4.In; import edu.prin ...
- 《算法》第一章部分程序 part 1
▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法 ● 代码,二分搜索 package package01; import java.util.Arrays; ...
- 《算法》第二章部分程序 part 5
▶ 书中第二章部分程序,加上自己补充的代码,包括利用优先队列进行多路归并和堆排序 ● 利用优先队列进行多路归并 package package01; import edu.princeton.cs.a ...
- 《算法》第二章部分程序 part 4
▶ 书中第二章部分程序,加上自己补充的代码,包括优先队列和索引优先队列 ● 优先队列 package package01; import java.util.Comparator; import ja ...
随机推荐
- messageBox 的几种显示方式
1.最简单的,只显示提示信息 MessageBox.Show("Hello~~~~"); 2. 可以给消息框加上标题. MessageBox.Show("There ar ...
- 关于bool 与boolean
关于bool的介绍,整理如下: bool 关键字是 System.Boolean 的别名.它用于声明变量来存储布尔值 true 和 false. 如果需要一个也可以有 null 值的布尔型变量,请使用 ...
- WebService的几种验证方式
转 http://www.cnblogs.com/yoshiki1895/archive/2009/06/03/1495440.html WebService的几种验证方式 1.1 WebS ...
- [视频播放] M3U8文件格式说明
M3U文件中可以包含多个tag,每个tag的功能和属性如下: #EXTM3U 每个M3U文件第一行必须是这个tag,请标示作用 #EXT-X-MEDIA-SEQUENCE:140651513 每一个m ...
- <亲测>用navicat连接mysql 8.0 报错2059
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded 2018年05月07日 15:56 ...
- [蓝桥杯]ALGO-81.算法训练_动态数组使用
从键盘读入n个整数,使用动态数组存储所读入的整数,并计算它们的和与平均值分别输出.要求尽可能使用函数实现程序代码.平均值为小数的只保留其整数部分. 样例输入: 样例输出: 样例输入: 样例输出: 题目 ...
- elasticsearch 5.1 别的机器无法访问9200端口
版权声明:作者:jiankunking 出处:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显 ...
- 在centos7中安装nodejs(npm )
我当前使用的是Centos7 首先在官网查看当前最新的版本 https://nodejs.org/dist/ 我现在最新的是 https://nodejs.org/dist/latest-v10.x/ ...
- windows下网络丢包模拟软件(Network Emulator for Windows Toolkit)
最近公司有一个直播的测试项目,需要模拟各种网络环境下的直播状态,最后找到一款这样的软件(如果有遇到更好的软件,望和网友多多交流) 介绍一款windows下的网络模拟器,可以模拟各种丢包或延迟的网络(N ...
- Lzma(7-zip)和zlib
Lzma(7-zip) 使用: 在C目录中有算法文件,进入Util\LzmaLib目录,编译生成LIB库,导出了以下两函数,LzmaCompress 为压缩函数,LzmaUncompress 为解压缩 ...