▶ 书中第三章部分程序,加上自己补充的代码,包括散列表、线性探查表

● 散列表

  1. package package01;
  2.  
  3. import edu.princeton.cs.algs4.Queue;
  4. import edu.princeton.cs.algs4.SequentialSearchST;
  5. import edu.princeton.cs.algs4.StdIn;
  6. import edu.princeton.cs.algs4.StdOut;
  7.  
  8. public class class01<Key, Value>
  9. {
  10. private static final int INIT_CAPACITY = 4; // 默认构造函数参数
  11. private int n; // 待插入元素数
  12. private int m; // 散列表尺寸
  13. private SequentialSearchST<Key, Value>[] st; // 散列表
  14.  
  15. public class01()
  16. {
  17. this(INIT_CAPACITY);
  18. }
  19.  
  20. public class01(int capacity)
  21. {
  22. m = capacity;
  23. st = (SequentialSearchST<Key, Value>[]) new SequentialSearchST[m];
  24. for (int i = 0; i < m; i++)
  25. st[i] = new SequentialSearchST<Key, Value>();
  26. }
  27.  
  28. public int size()
  29. {
  30. return n;
  31. }
  32.  
  33. public boolean isEmpty()
  34. {
  35. return size() == 0;
  36. }
  37.  
  38. private void resize(int capacity)
  39. {
  40. class01<Key, Value> temp = new class01<Key, Value>(capacity);
  41. for (int i = 0; i < m; i++)
  42. {
  43. for (Key key : st[i].keys())
  44. temp.put(key, st[i].get(key));
  45. }
  46. m = temp.m;
  47. n = temp.n;
  48. st = temp.st;
  49. }
  50.  
  51. public boolean contains(Key key)
  52. {
  53. if (key == null)
  54. throw new IllegalArgumentException("\n<contains> key == null.\n");
  55. return get(key) != null;
  56. }
  57.  
  58. private int hash(Key key)
  59. {
  60. return (key.hashCode() & 0x7fffffff) % m;
  61. }
  62.  
  63. public Value get(Key key)
  64. {
  65. if (key == null)
  66. throw new IllegalArgumentException("\n<get> key == null.\n");
  67. return st[hash(key)].get(key);
  68. }
  69.  
  70. public void put(Key key, Value val)
  71. {
  72. if (key == null)
  73. throw new IllegalArgumentException("\n<get> key == null.\n");
  74. if (val == null)
  75. {
  76. delete(key);
  77. return;
  78. }
  79. if (n >= 10 * m) // 平均链表长度不小于 10,扩容
  80. resize(2 * m);
  81. int i = hash(key);
  82. if (!st[i].contains(key))
  83. n++;
  84. st[i].put(key, val);
  85. }
  86.  
  87. public void delete(Key key)
  88. {
  89. if (key == null)
  90. throw new IllegalArgumentException("\n<delete> key == null.\n");
  91. if (!contains(key))
  92. return;
  93. int i = hash(key);
  94. if (st[i].contains(key))
  95. n--;
  96. st[i].delete(key);
  97. if (m > INIT_CAPACITY && n <= 2 * m) // 平均链表长度小于 2,缩容
  98. resize(m / 2);
  99. }
  100.  
  101. public Iterable<Key> keys()
  102. {
  103. Queue<Key> queue = new Queue<Key>();
  104. for (int i = 0; i < m; i++)
  105. {
  106. for (Key key : st[i].keys())
  107. queue.enqueue(key);
  108. }
  109. return queue;
  110. }
  111.  
  112. public static void main(String[] args)
  113. {
  114. class01<String, Integer> st = new class01<String, Integer>();
  115. for (int i = 0; !StdIn.isEmpty(); i++)
  116. {
  117. String key = StdIn.readString();
  118. st.put(key, i);
  119. }
  120. for (String s : st.keys())
  121. StdOut.println(s + " " + st.get(s));
  122. }
  123. }

● 线性探查表

  1. package package01;
  2.  
  3. import edu.princeton.cs.algs4.Queue;
  4. import edu.princeton.cs.algs4.StdIn;
  5. import edu.princeton.cs.algs4.StdOut;
  6.  
  7. public class class01<Key, Value>
  8. {
  9. private static final int INIT_CAPACITY = 4;
  10. private int n;
  11. private int m;
  12. private Key[] keys;
  13. private Value[] vals;
  14.  
  15. public class01()
  16. {
  17. this(INIT_CAPACITY);
  18. }
  19.  
  20. public class01(int capacity)
  21. {
  22. m = capacity;
  23. n = 0;
  24. keys = (Key[]) new Object[m];
  25. vals = (Value[]) new Object[m];
  26. }
  27.  
  28. public int size()
  29. {
  30. return n;
  31. }
  32.  
  33. public boolean isEmpty()
  34. {
  35. return size() == 0;
  36. }
  37.  
  38. private void resize(int capacity)
  39. {
  40. class01<Key, Value> temp = new class01<Key, Value>(capacity);
  41. for (int i = 0; i < m; i++)
  42. {
  43. if (keys[i] != null)
  44. temp.put(keys[i], vals[i]);
  45. }
  46. m = temp.m;
  47. keys = temp.keys;
  48. vals = temp.vals;
  49.  
  50. }
  51.  
  52. public boolean contains(Key key)
  53. {
  54. if (key == null)
  55. throw new IllegalArgumentException("\n<contains> key == null.\n");
  56. return get(key) != null;
  57. }
  58.  
  59. private int hash(Key key)
  60. {
  61. return (key.hashCode() & 0x7fffffff) % m;
  62. }
  63.  
  64. public Value get(Key key)
  65. {
  66. if (key == null)
  67. throw new IllegalArgumentException("\n<get> key == null.\n");
  68. for (int i = hash(key); keys[i] != null; i = (i + 1) % m) // 表荷载不会超过 1/2,所以不会绕圈
  69. {
  70. if (keys[i].equals(key))
  71. return vals[i];
  72. }
  73. return null;
  74. }
  75.  
  76. public void put(Key key, Value val)
  77. {
  78. if (key == null)
  79. throw new IllegalArgumentException("\n<get> key == null.\n");
  80. if (val == null)
  81. {
  82. delete(key);
  83. return;
  84. }
  85. if (n >= m / 2) // 荷载超过一半了,扩容
  86. resize(2 * m);
  87. int i;
  88. for (i = hash(key); keys[i] != null; i = (i + 1) % m)
  89. {
  90. if (keys[i].equals(key))
  91. {
  92. vals[i] = val;
  93. return;
  94. }
  95. }
  96. keys[i] = key;
  97. vals[i] = val;
  98. n++;
  99. }
  100.  
  101. public void delete(Key key)
  102. {
  103. if (key == null)
  104. throw new IllegalArgumentException("\n<delete> key == null.\n");
  105. if (!contains(key))
  106. return;
  107. int i = hash(key);
  108. for (; !key.equals(keys[i]); i = (i + 1) % m); // 找到目标元素
  109. keys[i] = null; // 删除目标元素
  110. vals[i] = null;
  111. for (i = (i + 1) % m; keys[i] != null; i = (i + 1) % m) // 在下一个 null 之前,所有元素重新插入
  112. {
  113. Key keyToRehash = keys[i];
  114. Value valToRehash = vals[i];
  115. keys[i] = null;
  116. vals[i] = null;
  117. n--;
  118. put(keyToRehash, valToRehash);
  119. }
  120. n--;
  121. if (n > 0 && n <= m / 8) // 荷载小于 1/8, 缩容
  122. resize(m / 2);
  123. }
  124.  
  125. public Iterable<Key> keys()
  126. {
  127. Queue<Key> queue = new Queue<Key>();
  128. for (int i = 0; i < m; i++)
  129. {
  130. if (keys[i] != null)
  131. queue.enqueue(keys[i]);
  132. }
  133. return queue;
  134. }
  135. private boolean check()
  136. {
  137. if (m < 2 * n) // 检查容量
  138. {
  139. System.err.println("\n<check> m < 2 * n.\n");
  140. return false;
  141. }
  142. for (int i = 0; i < m; i++) // 检查 hash
  143. {
  144. if (keys[i] == null)
  145. continue;
  146. if (get(keys[i]) != vals[i])
  147. {
  148. System.err.println("\n<check> hash error at i = ", i, ", key[i] = ", get(keys[i]), ", val[i] = ", vals[i], ".\n");
  149. return false;
  150. }
  151. }
  152. return true;
  153. }
  154.  
  155. public static void main(String[] args)
  156. {
  157. class01<String, Integer> st = new class01<String, Integer>();
  158. for (int i = 0; !StdIn.isEmpty(); i++)
  159. {
  160. String key = StdIn.readString();
  161. st.put(key, i);
  162. }
  163. for (String s : st.keys())
  164. StdOut.println(s + " " + st.get(s));
  165. }
  166. }

《算法》第三章部分程序 part 4的更多相关文章

  1. 《算法》第三章部分程序 part 6

    ▶ 书中第三章部分程序,加上自己补充的代码,包含双向索引表.文建索引.稀疏向量类型 ● 双向索引表 package package01; import edu.princeton.cs.algs4.S ...

  2. 《算法》第三章部分程序 part 5

    ▶ 书中第三章部分程序,加上自己补充的代码,包含公共符号表.集合类型 ● 公共符号表,用于普通查找表的基本类 package package01; import java.util.NoSuchEle ...

  3. 《算法》第三章部分程序 part 3

    ▶ 书中第三章部分程序,加上自己补充的代码,红黑树 ● 红黑树,大部分方法与注释与二叉树相同 package package01; import java.util.NoSuchElementExce ...

  4. 《算法》第三章部分程序 part 2

    ▶ 书中第三章部分程序,加上自己补充的代码,平衡二叉搜索树 ● 平衡二叉搜索树 package package01; import java.util.NoSuchElementException; ...

  5. 《算法》第三章部分程序 part 1

    ▶ 书中第三章部分程序,加上自己补充的代码,包括单词频率统计,(单链表)顺序查找表,二分查找表 ● 单词频率统计 package package01; import edu.princeton.cs. ...

  6. 《算法》第二章部分程序 part 3

    ▶ 书中第二章部分程序,加上自己补充的代码,包括各种优化的快排 package package01; import edu.princeton.cs.algs4.In; import edu.prin ...

  7. 《算法》第一章部分程序 part 1

    ▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法 ● 代码,二分搜索 package package01; import java.util.Arrays; ...

  8. 《算法》第二章部分程序 part 5

    ▶ 书中第二章部分程序,加上自己补充的代码,包括利用优先队列进行多路归并和堆排序 ● 利用优先队列进行多路归并 package package01; import edu.princeton.cs.a ...

  9. 《算法》第二章部分程序 part 4

    ▶ 书中第二章部分程序,加上自己补充的代码,包括优先队列和索引优先队列 ● 优先队列 package package01; import java.util.Comparator; import ja ...

随机推荐

  1. linux与Windows使用编译区别及makefile文件编写

    一.Windows与:Linux嵌入式开发区别 Windows下编辑.编译.执行 编辑: sourceInsight:ADS: 编译:指定链接地址,指定链接顺序,编译 执行:烧写到单板再启动 Linu ...

  2. mysql 高可用架构

    什么是高可用 不可用出现的情况 如何实现高可用 第一种方法 第二种方法 MMM 和 MHA MHA更好的处理方式 安装步骤 优缺点 读写分离

  3. 让SQL SERVER自动清理掉处于SLEEPING状态超过30分钟的进程(转)

    原文地址:http://www.itpub.net/thread-809758-1-1.html use master go ) drop procedure [dbo].[p_killspid] G ...

  4. GoJS拖动设计

    http://192.168.0.149:8035/gojs/intro/groups.html http://192.168.0.149:8035/gojs/intro/ports.html htt ...

  5. Java序列化的理解与学习

    1.什么是Java序列化 Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比 JVM的生命周期更长.但在现实应 ...

  6. ==和is

    is是比较两个引用是否指向了同一个对象(引用比较) ==是比较两个对象是否相等 数字在:-5~256之间的时候用来赋值的内存地址是不变的

  7. Python——ipython(python programming)

    Tab自动补充 Ctrl+c中断程序 ?帮助调出文档   _得到上次的结果 ,__的到上上次结果,___得到上上次结果  %开头的为魔术命令  %timeit 得到运算时间,多次求平均  %%time ...

  8. JSON: 介绍、应用

    ylbtech-JSON:  介绍.应用 JSONP(JSON with Padding)是 JSON 的一种“使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据. 为什么我们从不同的 ...

  9. [UE4]Return Node节点好用法

    蓝图自定义函数中,碰到“Return Node”也会推出当前的函数,跟高级语言的“return”是一样的用法

  10. sqlserver创建数据库

    --指向当前要使用的master数据库,向master数据库中注册创建信息 use master go --创建数据库 create database StudentManageDB on prima ...