《算法》第三章部分程序 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 ...
随机推荐
- 跟着未名学 - 录屏套件 Camtasia Studio
目录 Camtasia Recorder. 1 Camtasia Studio.. 2 时间线... 2 渲染... 5 Camtasia MenuMaker. 6 Camtasia Play. 6 ...
- 关于JFame 屏幕居中显示的问题
场景: 在利用 JAVA 的 Swing 开发 C/S 架构 的前端界面 目的: 想让 JFrame 居中显示在整个 屏幕的正中位置 方法一:JFrame frame = new JFr ...
- 找不到 EntityType “ ” 的映射和元数据信息。
意思是: 数据库里边有添加的新字段DB1,而程序中的的实体即“元数据”中没有这个新字段Et1,由于EntityFramework更新模型时已自动默认对DB1和Et1进行了映射(默认认为实体中存在这个字 ...
- 【java】之Method和Field反射获取和设置属性值
package com.javaluna.reflect; import java.lang.reflect.Field; import java.lang.reflect.Method; impor ...
- Quartz不用配置文件配置启动
StdSchedulerFactory schedulerFactory = null; try { schedulerFactory = new StdSchedulerFactory(); Pro ...
- Android开发之Activity生命周期篇
一.Activity: 1.Activity:Activity是一个与用记交互的系统模块,几乎所有的Activity都是和用户进行交互的. 2.在Android中Activity主要是用来做控制的,它 ...
- 【C#】语音识别 - System.Speech
一个有趣的东西,今后可能用得上. C#语音识别:在命名空间 System.Speech下SpeechSynthesizer可以将文字转换成语音 贴出代码: public partial class F ...
- [转][layui]table 的一个BUG
转换静态表格,一直只能显示 10 行,研究发现解决方法有两个:1.参数里: limit: 30, 添加参数以确保显示更多行2.修改 table.js 里面的 F.prototype.config ,添 ...
- python之路——2
王二学习python的笔记以及记录,如有雷同,那也没事,欢迎交流,wx:wyb199594 复习 1.编译型:一次性将全部的代码编译成二进制文件 c c++ 优点:运行效率高 缺点:开发速度慢,不能跨 ...
- [UE4]认识Decorator
Decorator装饰器:即为其他行为树系统中的条件语句,附着于一个Composite(组合节点)或者Task(任务节点),并定义树中的一个分支或者单个节点是否可被执行. Decorator装饰器节点 ...