1.散列表的接口类

package cn.usst.hashtable;

/**
* 散列表的接口类
* @author G-Xia
*
*/
public interface HashTable {
//向散列表中插入一个keyword为theKey的元素obj,若成功返回真否则返回假
boolean insert(Object theKey, Object obj); //向散列表中查找并返回给定keywordtheKey相应的元素,若查找失败返回空
Object search(Object theKey); //从散列表中删除keyword为theKey的元素,若删除成功返回真否则返回假
boolean delete(Object theKey); //返回散列表中已存在的元素个数
int size(); //返回散列表的容量,即散列表的空间大小m的值
int capacity(); //推断散列表是否为空,若为空则返回真 否则返回假
boolean isEmpty(); //清楚散列表的全部元素。使之变成一个空表
void clear(); //输出散列表中保存的全部keyword和相应的元素
void output(); }

2.採用开放地址法处理冲突的数组存储类

package cn.usst.hashtable.seqhashtable;

import cn.usst.hashtable.HashTable;
/**
* 採用线性探測法处理冲突进行散列存储
* @author G-Xia
*
*/
public class SeqHashTable implements HashTable { private int m; //保存散列表的容量
private Object[] key; //定义保存元素keyword的数组
private Object[] ht; //定义保存散列表的数组
private int n; //散列表中已有的元素个数
private Object tag; //元素内容被删除后的keyword删除标记 //散列函数,採用除
private int h(Object theKey){
//留余数发,若參数不是整数,应设法转换成整数
return (Integer)theKey%m;
} public SeqHashTable(int mm, Object tag){
//假定散列表的容量至少为13
if(mm < 13){
m = 13;
}else{
m = mm;
}
n=0;
key = new Object[m];
ht = new Object[m];
this.tag = tag; //置keyword删除标记为參加tag的值
} @Override
public boolean insert(Object theKey, Object obj) {
int d = h(theKey);
int temp = d;
while(key[d] != null && key[d].equals(tag) != true){
//用线性探測法处理冲突,寻找插入位置
if(key[d].equals(theKey) == true)
break; //元素已经存在,则退出循环
d = (d+1) % m;
if(d == temp){ //查找一周后扔无位置,应重组散列表或退出执行
System.out.println("散列表无空间,退出执行");
System.exit(1);
}
}
if(key[d] == null || key[d].equals(tag)==true){
//找到插入位置,插入新的keyword和元素并返回真
key[d] = theKey;
ht[d] = obj;
n++;
return true;
}else{ //用新元素obj改动已存在的元素并返回假
ht[d] = obj;
return false;
}
} @Override
public Object search(Object theKey) {
int d= h(theKey);
int temp = d;
while(key[d] != null){
if(key[d].equals(theKey)){
return ht[d];
}else{
d = (d+1) % m;
}
if(d == temp)
return null;
} return null;
} @Override
public boolean delete(Object theKey) {
int d = h(theKey);
int temp = d;
while(key[d] != null){
if(key[d].equals(theKey)){
key[d] = tag;
ht[d] = null;
n--;
return true;
}else{
d = (d+1)%m;
}
if(d==temp){
return false;
}
}
return false;
} @Override
public int size() {
return n;
} @Override
public int capacity() {
return m;
} @Override
public boolean isEmpty() {
return n==0;
} @Override
public void clear() {
for(int i=0; i<m; i++){
key[i] = null;
ht[i] = null;
}
n=0;
} @Override
public void output() {
for(int i=0; i<m; i++){
if(key[i]==null || key[i].equals(tag))
continue;
System.out.println("(" + key[i] + " " + ht[i] + "),");
}
System.out.println();
} }

3.使用链接法处理冲突的连接存储类

节点类型

package cn.usst.hashtable.linkhashtable;

/**
* 採用链接发处理冲突的散列表中节点的类型
* @author G-Xia
*
*/
public class HashNode {
Object key;
Object element;
HashNode next;
public HashNode(Object theKey, Object obj){
key = theKey;
element = obj;
next = null;
}
}

实现方法

package cn.usst.hashtable.linkhashtable;

import cn.usst.hashtable.HashTable;

public class LinkHashTable implements HashTable {

	private int m;			//保存散列表的容量
private HashNode[] ht; //定义保存散列表的数组
private int n; //散列表中已有的元素个数 //散列函数
private int h(Object theKey){
return (Integer)theKey % m;
} public LinkHashTable(int mm){
if(mm < 13){
m = 13;
}else{
m = mm;
}
n = 0;
ht = new HashNode[m];
} @Override
public boolean insert(Object theKey, Object obj) {
int d = h(theKey);
HashNode p = ht[d];
// 从单链表中顺序查找keyword为theKey的节点
while(p != null){
if(p.key.equals(theKey) == true)
break;
else
p = p.next;
} if(p != null){ //用新元素obj改动已有节点的元素值并返回假
p.element = obj;
return false;
}else{
p = new HashNode(theKey, obj);
p.next = ht[d];
ht[d] = p;
n++;
return true;
}
} @Override
public Object search(Object theKey) {
int d = h(theKey);
HashNode p = ht[d];
while(p!=null){
if(p.key.equals(theKey))
return p.element;
else
p = p.next;
}
return null;
} @Override
public boolean delete(Object theKey) {
int d = h(theKey);
HashNode p = ht[d], q = null; //p指向表头节点,q指向前驱节点。初始为空
while(p != null){
if(p.key.equals(theKey))
break;
else{
q = p;
p = p.next;
}
}
if(p == null) //没有删除的元素,返回false
return false;
else if(q == null) //删除的是表头节点
ht[d] = p.next;
else //删除的是非表头节点
q.next = p.next;
n--; return true;
} @Override
public int size() {
return n;
} @Override
public int capacity() {
return m;
} @Override
public boolean isEmpty() {
return n==0;
} @Override
public void clear() {
for(int i=0; i<m; i++){
ht[i] = null;
}
n=0;
} @Override
public void output() {
for(int i=0; i<m; i++){
HashNode p = ht[i];
while(p != null){
System.out.println("(" + p.key + " " + p.element + "),");
p = p.next;
}
}
System.out.println();
} }

4.測试方法

public class SeqHashTableTest {
@Test
public void seqHashTableTest(){
int[] a = {18, 75, 60, 43, 54, 90, 46, 31, 58, 73, 15, 34};
String[] b = {"180", "750", "600", "420", "540", "900", "460",
"310", "580", "730", "150", "340"};
HashTable tb = new SeqHashTable(17, -1);
//HashTable tb = new LinkHashTable(17);
for(int i=0; i<a.length; i++){
tb.insert(a[i], b[i]);
}
System.out.println("输出散列表中的全部元素:");
tb.output();
System.out.println("散列表的容量:" + tb.capacity());
System.out.println("散列表中元素的个数:" + tb.size());
for(int i=0; i<a.length; i+=3){
tb.delete(a[i]);
}
tb.insert(88, "880");
tb.insert(75, "7500");
System.out.println("经插入、删除、改动后,散列表为:");
tb.output();
System.out.println("散列表的容量:" + tb.capacity());
System.out.println("散列表中元素的个数:" + tb.size()); for(int i=0; i<4; i++){
String x = (String)(tb.search(a[i]));
if(x != null)
System.out.println(a[i] + " " + x);
else
System.out.println(a[i] + "为keyword的元素没有找到! ");
}
}
}

HashTable的数组和连接两种实现方法(Java版本号)的更多相关文章

  1. java中数组复制的两种方式

    在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...

  2. C++ 数组遍历的两种方式

    C++ 数组遍历的两种方式: #include <iostream> using namespace std; int main() { // 一维数组 ] = {, , , , }; / ...

  3. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  4. 关于Unity的两种调试方法

    Unity的两种调试方法 1.Debug.Log()输出语句调试,平时经常用这个 2.把MonoDevelop和Unity进行连接后断点调试 先把编辑器选择为MonoDevelop,Edit----& ...

  5. win7系统不能用telnet命令的两种解决方法

    电脑专业人员对telnet命令都不陌生了,Telnet当成一种通信协议,在日常工作中,经常面对网络问题的人都会用到telnet命令,因为简单有效,可以帮助更快的找出问题.要是在使用过程中碰到win7纯 ...

  6. 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结

    史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...

  7. Nodejs回调加超时限制两种实现方法

    odejs回调加超时限制两种实现方法 Nodejs下的IO操作都是异步的,有时候异步请求返回太慢,不想无限等待回调怎么办呢?我们可以给回调函数加一个超时限制,到一定时间还没有回调就表示失败,继续后面的 ...

  8. tkinter中控件menu的两种组织方法

    tkinter中,菜单控件组织方法有两种,使用中常出现混淆,为明晰各个正确用法,特整理撰写此博文.菜单控件的组织实际上是通过一个“母菜单”和“子菜单”构成,“母菜单”一方面与master连接(即与依附 ...

  9. bind()函数的深入理解及两种兼容方法分析

    在JavaScript中,bind()函数仅在IE9+.Firefox4+.Chrome.Safari5.1+可得到原生支持.本文将深入探讨bind()函数并对两种兼容方法进行分析比较.由于本文将反复 ...

随机推荐

  1. 使用代码辅助生成工具CodeSmith -- 生成NHibernate的映射文件

    首先下载CodeSmith工具:在百度云中,在CodeSmith文件夹中. 安装,使用激活工具激活. 然后下载NHibernate模板,也是在百度云中,在CodeSmith文件夹中. 之后直接点击NH ...

  2. sql server日期字段值的比较

    sql server中对日期字段值的比较 sql server中对日期字段的比较方式有多种,介绍几种常用的方式:用northwind库中的employees表作为用例表.1.between...and ...

  3. 浅析js的执行顺序

    javascript是一种描述型的脚本语言,是一种解析语言,由浏览器动态解析,不同种类的浏览器不同版本的浏览器对于js的解析有着微小的差别,不同浏览器的js解析引擎效率也有高低,下面来给大家分析一下j ...

  4. MVC控制器里面使用dynamic和ExpandoObject

    MVC控制器里面使用dynamic和ExpandoObject 在很多时候,我们在数据库里面定义表字段和实际在页面中展示的内容,往往是不太匹配的,页面数据可能是多个表数据的综合体,因此除了我们在表设计 ...

  5. perl 登陆电信猫

    登陆电信猫: use LWP::UserAgent; use HTTP::Date qw(time2iso str2time time2iso time2isoz); use Net::Ping; u ...

  6. 升级版:深入浅出Hadoop实战开发(云存储、MapReduce、HBase实战微博、Hive应用、Storm应用)

          Hadoop是一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运算和存储.Hadoop实现了一个分布式文件系 ...

  7. ORA-00942:表或视图不存在(低级错误)

    在好多时候.调试PL/SQL对象时会报.ORA-00942 看看错误原因吧: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFjc29uX2JhaQ== ...

  8. 九道大型软件公司.net面试题!一定得看(附答案)

    1:a=10,b=15,在不用第三方变量的前提下,把a,b的值互换   2:已知数组int[] max={6,5,2,9,7,4,0};用快速排序算法按降序对其进行排列,并返回数组   3:请简述面向 ...

  9. 进阶: 案例八: Drag and Drop(动态)

    1.节点 2.UI 3. 4.方法: METHOD wddomodifyview . DATA: lo_container TYPE REF TO cl_wd_uielement_container, ...

  10. 基础知识(9)- Swing用户界面组件

    9.1 Swing和模型-视图-控制器设计模式  9.1.1 设计模式  9.1.2 模型-视图-控制器模式  9.1.3 Swing按钮的模型-视图-控制器分析 9.2 布局管理概述  9.2.1 ...