散列表(拉链法与线性探测法)Java实现
package practice; import java.security.Principal;
import java.util.Scanner; import edu.princeton.cs.algs4.*; public class TestMain {
public static void main(String[] args) {
//50个随机数字
Integer[] a = new Integer[50];
for (int i = 0; i < a.length; i++) {
a[i] = new Integer(StdRandom.uniform(1, 1000));
} //50个随机字符串
char ch = 'a';
int chl;
String []b = new String[50];
for (int i = 0; i < b.length; i++) {
int sl = StdRandom.uniform(1, 10);
b[i] = new String();
for (int j = 0; j < sl; j++) {
chl = StdRandom.uniform(0, 23);
b[i] += (char)(ch + chl);
}
}
//构建散列表
/*SeparateChainingHashST<String, Integer> hashmap = new SeparateChainingHashST<String, Integer>(50); for (int i = 0; i < b.length; i++) {
hashmap.put(b[i], a[i]);
}*/ LinearProbingHashST<String, Integer> hashmap = new LinearProbingHashST<String, Integer>();
//占有率最好在1/2和1/8之间(数学证明结果),占有率越高,查找操作越难以命中,如果占有率为1,输入没有的值就会无限循环
for (int i = 0; i < b.length; i++) {
hashmap.put(b[i], a[i]);
} hashmap.show(); String KeyShuRu;
Scanner ShuRu = new Scanner(System.in);
while (true) {
KeyShuRu = ShuRu.nextLine();
System.out.println(hashmap.get(KeyShuRu));
hashmap.delete(KeyShuRu);
hashmap.show();
}
}
} /*
* 基于拉链法的散列表
* 散列值相同时,用一个链表储存
*/
class SeparateChainingHashST<K, V> {
private K key;
private V value;
private int M;
private SequentialSearchST<K, V>[] st;
public SeparateChainingHashST(int M) {
st = (SequentialSearchST<K, V>[]) new SequentialSearchST[M];
for (int i = 0; i < M; i++) {
st[i] = new SequentialSearchST();
}
}
/*
* 插入
*/
public void put(K key, V value) {
st[hash(key)].put(key, value);
}
/*
* 查找
*/
public V get(K key) {
return st[hash(key)].get(key);
}
/*
* 输出整个表
*/
public void show() {
for (int i = 0; i < M; i++) {
System.out.print("chain ["+i+"] ");
st[i].show();
System.out.println();
}
}
/*
* 获取哈希值
*/
private int hash(K key) {
return (key.hashCode() & 0x7fffffff) % M; //可以返回一个M以内的正整数hash值 }
} /*
* 基于线性探测法的散列表
* 散列值处已经有元素,就把值存在散列值处的后面(触底返0)
*/
class LinearProbingHashST<K, V> {
private K[] key;
private V[] value;
private int M = 16; //线性探测表的大小
private int N; //表中键值对的多少
public LinearProbingHashST() {
key = (K[]) new Object[M];
value = (V[]) new Object[M];
}
/*
* 插入
*/
public void put(K key, V value) {
if (N >= M/2) { resize(2*M);} int hashv = hash(key);
while (true) {
if (hashv == M) { hashv = 0;} if (this.key[hashv] == null) {
this.key[hashv] = key;
this.value[hashv] = value;
N++;
break;
}
else if (key.equals(this.key[hashv])) {
this.value[hashv] = value;
break;
} hashv++;
}
}
/*
* 查找
*/
public V get(K key) {
int hashv = hash(key);
while (true) {
System.out.println("hashv = "+hashv);
if (this.key[hashv] == null) { return null;}
if (key.equals(this.key[hashv])) { return this.value[hashv];}
hashv++;
if (hashv == M) { hashv = 0;}
}
}
/*
* 输出表
*/
public void show() {
for (int i = 0; i < M; i++) {
System.out.printf("[%d] %-10s%4d \n", i, key[i], value[i]);
}
}
/*
* 删除元素
*/
public void delete(K key) {
//将元素删除
int hashv = hash(key);
while (true) {
if (this.key[hashv] == null) {
System.out.println("the value is not exist");
return;
} if (key.equals(this.key[hashv])) {
this.key[hashv] = null;
this.value[hashv] = null;
N--;
System.out.println("The value has been deleted");
break;
} hashv++;
if (hashv == M) { hashv = 0;}
} //将后面的元素全部重新插入
hashv = hash(key) + 1;
while (this.key[hashv] != null) {
K tempkey = this.key[hashv];
V tempvalue = this.value[hashv]; this.key[hashv] = null;
this.value[hashv] = null;
N--; put(tempkey, tempvalue); hashv ++;
if (hashv == M) { hashv = 0;}
}
}
/*
* 获取哈希值
*/
private int hash(K key) {
return (key.hashCode() & 0x7fffffff) % M;
}
/*
* 改变大小
*/
private void resize(int M) {
this.M = M;
K[] tempkey = (K[]) new Object[M];
V[] tempvalue = (V[]) new Object[M]; for (int i = 0; i < key.length; i++) {
tempkey[i] = key[i];
tempvalue[i] = value[i];
} key = tempkey;
value = tempvalue;
}
} /*
* 链表
*/
class SequentialSearchST<K, V> {
private Node head;
private Node root;
class Node {
private K key;
private V value;
private Node next;
private Node(K key, V value) {
this.key = key;
this.value = value;
}
/*
* 输出节点
*/
private void show() {
System.out.printf("%-10s%4d ", key, value);
}
}
/*
* 插入
*/
public void put(K key, V value) {
if (root != null) {
Node tempnode = root;
while (true) {
if (key.equals(tempnode.key)) {
tempnode.value = value;
return;
} if (tempnode == head) { break;}
tempnode = tempnode.next;
}
}
//上面是避免有重复的key
Node newnode = new Node(key, value);
if (root == null) {
root = newnode;
head = newnode;
return;
} head.next = newnode;
head = newnode;
}
/*
* 查找
*/
public V get(K key) {
Node tempnode = root; while (!(tempnode == null)) {
if (key.equals(tempnode.key)) { return tempnode.value;}
tempnode = tempnode.next;
} return null;
}
/*
* 输出整条链
*/
public void show() {
Node tempnode = root;
while (!(tempnode == null)) {
tempnode.show();
tempnode = tempnode.next;
}
} }
散列表(拉链法与线性探测法)Java实现的更多相关文章
- Hash开散列 拉链法
#include<iostream> #include<cstdio> using namespace std; const int maxn=1000007; struct ...
- PTA 7-42 整型关键字的散列映射(手写哈希表的线性探测法)
本题考点: 整型哈希表的线性探测法 给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射到长度为P的散列表中.用线性探测法解决冲突. 输入格式: 输入第一行首先给出两个正整数N(≤10 ...
- Hash Table(散列表)
这篇主要是基础的数据结构学习,写的时候才明白了书上说到的一些问题,由于该篇仅仅只是对这种数据结构进行一个理解,所以很基础,关于h(x)函数也只是简单的运用了除法散列,然后为了应对冲突,我用的是链接法. ...
- 【PHP数据结构】散列表查找
上篇文章的查找是不是有意犹未尽的感觉呢?因为我们是真真正正地接触到了时间复杂度的优化.从线性查找的 O(n) 直接优化到了折半查找的 O(logN) ,绝对是一个质的飞跃.但是,我们的折半查找最核心的 ...
- 【Java集合学习】HashMap源码之“拉链法”散列冲突的解决
1.HashMap的概念 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io ...
- Java数据结构与算法解析(十二)——散列表
散列表概述 散列表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 散列表的思路很简单,如果所有的键都是整数,那么就可以使用一个简单 ...
- 【Java】 大话数据结构(13) 查找算法(4) (散列表(哈希表))
本文根据<大话数据结构>一书,实现了Java版的一个简单的散列表(哈希表). 基本概念 对关键字key,将其值存放在f(key)的存储位置上.由此,在查找时不需比较,只需计算出f(key) ...
- Java数据结构和算法(一)散列表
Java数据结构和算法(一)散列表 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 散列表(Hash table) 也叫哈希表 ...
- 数据结构---散列表查找(哈希表)概述和简单实现(Java)
散列表查找定义 散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,是的每个关键字key对应一个存储位置f(key).查找时,根据这个确定的对应关系找到给定值的key的对应f(key) ...
随机推荐
- 从零自学Hadoop(24):Impala相关操作上
阅读目录 序 数据库相关 表相关 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 序 ...
- pwnable.kr col之write up
Daddy told me about cool MD5 hash collision today. I wanna do something like that too! ssh col@pwnab ...
- js中this的指向总结
// this要在执行时才能确认值,定义时无法确认.下面是常见的几种this指向. //1.在构造函数执行 function Obj(name,age){ //1.实例化时:会创建一个 空对象 ...
- Intger To Roman
这题意思是将一个输入的整型阿拉伯数字转化为罗马数字. 思路是将1-10对应的罗马数字放在字符串数组里,然后发现数据变化规律即可,eg:389 = 300 + 89 +9 分别对应的罗马数字. publ ...
- CentOS Linux 系统 英文 改中文
CentOS Linux 系统 英文 改中文 首先,使用root用户登录Linux系统,然后进入打开终端(桌面上右键第四个选项,应该是),然后进入到etc/sysconfig目录下
- 敏捷开发之产品日日新,一步通之---自动化代码构建->自动化打包->自动化安装部署
本文将介绍如何自动化实现代码构建,自动化代码打包成exe安装包,自动化安装到测试环境.通过计划任务的方式,每天自动化发布最新的产品供老板展示,供测试人员使用,真正实现敏捷的快速迭代. 自动代码构建 自 ...
- 解决Nuget:https://api.nuget.org/v3/index.json 访问不了的问题
最近在家中用使用VS编译项目时,Nuget包一直下载不了,直接在浏览器中访问https://api.nuget.org/v3/index.json ,浏览器也打不开网址.把https协议改成http协 ...
- ArrayList 和Vector ,HashTable和HashMap异同
相同点: 1.都实现了List接口(List接口继承自Collection接口) 2.有序集合,数据可重复,可按索引号取值(而HashSet无序,不可重复) 不同点: 1.Vector是线程安全的,而 ...
- web前端+javascript+h5电子书籍和实战分享
有很多前端伙伴们学习前端很多了,但是如何能成为优秀的程序员呢,前端必学的知识点相信学习前端的伙伴们心里都非常清楚.主要的三要素包括HTML.CSS和JavaScript.那么学好JavaScript是 ...
- TestNG--入门介绍教程
阅读目录 TestNG介绍 在Eclipse中在线安装TestNG 在Eclipse中离线安装Testng TestNG最简单的测试 TestNG的基本注释 TestNG中如何执行测试 使用testt ...