`
zhong_qm
  • 浏览: 9879 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Hash的简单介绍与java代码实现

阅读更多
这是我在初步接触后,写的关于哈希表的插入、查找、删除、遍历、更改几个基本操作的java代码思路。
哈希表是种数据结构,它可以提供快速的插入操作和查找操作,其余优缺点不加以讨论。但一般的操作必须是根据key值进行。所谓的key值,是唯一标识数据信息的特殊数据,不可重复,如学生的学号,人民的身份证号码。在计算机中,key值可是内存地址,亦可自我设定。下面是关于哈希表的其中一个方式。

在数据就是key值的情况下,将要存放的数据除以某个整数,所得的余数作为放置位置的依据。如上图,设一个哈希表数组中有13个位置,取除数为13,由取余数法知:01数据放置在1号位置,55放置在3号,同时,有时余数可能重复,如14,余数为1,我也将其放置在1号位置,以此类推,可将整数放入一个与其本身有所联系的位置。这就是一种哈希表的简单介绍。
在用java代码实现时,思路是:
key值自我设定,由0开始递增,
在同一个位置只可放置最多三个数据,多的建立下一个数组(一组位置的设定)。
数组间的元素联系采用单向链表,同一个位置的数据亦采用单向链表的方法

先进行一些设置:
public class HashLinkArray {
private int hashLALength = 10;//链表数组的长度
private int hashLALLength = 3;//同一个位置最多可放置的数据个数


因为链表数组是由结点相互联系,它在不同的数组指示我们按一定的顺序进行查找。要先写一个结点类:

public class HashLinkNode {

public  Object[] hlla_Next;//结点数组
public HashLinkNode parent;//父结点
public HashLinkNode child;//子结点
/**
* 设置结点数组
* @param hlla_c 结点数组
*/
public void setHashLinkNode_Array(Object[] hlla_c){
this.hlla_Next=hlla_c;
}
/**
* 得到数组
* @return
*/
public Object[] getHashLinkNode_Array(){
return hlla_Next;
}

}

在用此个结点类中,我们可以开始建立链表数组

public void setHashLinkArray() {
HashLinkNode hln = null;
//第一次建立哈希数组
if (hashLinkArrayNum == 0) {
//哈希数组
Object[] hla = new Object[hashLALength];
hln = new HashLinkNode();
hln.parent = hln;
first_Node = hln;
//设置数组
hln.setHashLinkNode_Array(hla);
hashLinkArrayNum++;

} else {///////非第一次建立/////////////////
hln = first_Node;
while (true) {

if (hln.child != null) {
hln = hln.child;
} else {
HashLinkNode newNode = new HashLinkNode();
newNode.parent = hln;
hln.child = newNode;

Object[] hla = new Object[hashLALength];
newNode.setHashLinkNode_Array(hla);
hashLinkArrayNum++;
break;
}

}

}

}


此前说过,在同一个位置,可最多放置三个数据,这三个数据之间的关系也用单向链表进行表示,再写一个结点类:

public class HashElemNode {
HashElemNode p;//父结点
HashElemNode c;//子结点
int key;//key值
Object newelem;//数据信息
/**
* 得到数据信息
* @return
*/
public Object getElem(){
return newelem;
}

}

增加数据时,首先要计算余数,然后遍历,从第一个数组开始,先得到它的位置,再判断能否放在这个位置,如果不能,再尝试下一个数组,如果没有下一个数组,则建立一个。

/**
* 增加哈希表中的元素
*
* @param newelem
*            新的元素
*/
//key值自定义
public static int key = 0;
public void addHashelem(Object newelem) {
//取余
int lo_key = key % hashLALength;
//首先建立第一个数组
if (hashLinkArrayNum == 0) {
setHashLinkArray();
}
//数据元素的结点
HashElemNode newelemnode = new HashElemNode();
newelemnode.key = key;
newelemnode.newelem = newelem;
//从第一个数组开始遍历
HashLinkNode node = first_Node;
while (true) {
//若此位置没有元素
if (node.getHashLinkNode_Array()[lo_key] == null) {
key++;
node.getHashLinkNode_Array()[lo_key] = newelemnode;
newelemnode.p = newelemnode;
System.out.println("第n组" + hashLinkArrayNum + "key0 is"
+ newelemnode.key + "数据:" + newelemnode.newelem);

break;

} else {
HashElemNode elemnode = (HashElemNode) node
.getHashLinkNode_Array()[lo_key];
if (elemnode.c == null) {//只有一个元素
key++;
newelemnode.p = elemnode;
elemnode.c = newelemnode;
System.out.println("第n组" + hashLinkArrayNum + "key1 is"
+ newelemnode.key + "数据:" + newelemnode.newelem);
break;
} else {//只有两个元素
if (elemnode.c.c == null) {
key++;
newelemnode.p = elemnode.c;
elemnode.c.c = newelemnode;
System.out
.println("第n组" + hashLinkArrayNum + "key2 is"
+ newelemnode.key + "数据:"
+ newelemnode.newelem);
break;
} else {
//前面的数组的此位置都满了,建立一个新的数组
if (node.child == null) {
setHashLinkArray();
System.out.println("第n组" + hashLinkArrayNum
+ "======================================");
}
//有三个元素,遍历下一个数组
node = node.child;

}
}
}

}

}



接下来可以进行元素的遍历:

/**
* 遍历哈希表
*/
public int travelHash() {
//从第一个数组开始
HashLinkNode arraynode = first_Node;
int arraynum = 1;//数组个数
int elemnum = 0;//元素个数
while (true) {
for (int i = 0; i < hashLALength; i++) {
//该位置的第一个元素,如果有
if (arraynode.getHashLinkNode_Array()[i] != null) {
HashElemNode elemnode = (HashElemNode) arraynode
.getHashLinkNode_Array()[i];
System.out.println(elemnum + "第" + arraynum + "组" + "key是"
+ elemnode.key + "%后是" + elemnode.key
% hashLALength + "数据是" + elemnode.newelem);
elemnum++;
if (elemnode.c != null) {//第二个
System.out.println(elemnum + "第" + arraynum + "组"
+ "key是" + elemnode.c.key + "%后是"
+ elemnode.c.key % hashLALength + "数据是"
+ elemnode.c.newelem);
elemnum++;

if (elemnode.c.c != null) {//第三个
System.out.println(elemnum + "第" + arraynum + "组"
+ "key是" + elemnode.c.c.key + "%后是"
+ elemnode.c.c.key % hashLALength + "数据是"
+ elemnode.c.c.newelem);
elemnum++;
}

}

}

}

if (arraynode.child != null) {
//遍历下一个数组
arraynode = arraynode.child;
} else {
//退出循环
break;
}

}
return elemnum;

}




通过遍历,我们已经可以找到方法,查到表中每一个元素,删除操作就是把父子结点的更替,或是去掉,只要在遍历的条件上增加key值的判断。查找也是,只需返回这个数据的结点,便可得到数据,不再介绍。
0
0
分享到:
评论

相关推荐

    Rabin-Karp字符串搜索算法介绍和java代码实现

    下面是该算法的概念、特点、优缺点、适用场景和 Java 代码实现。 概念:Rabin-Karp 字符串搜索算法是一种基于哈希的字符串匹配算法,用于在一个文本中查找一个模式字符串的出现。使用哈希函数来计算模式字符串和...

    Hash算法大全(java实现)参照.pdf

    例如,FNV1算法(未在上述代码中直接给出Java实现),它是一种广泛使用的非加密Hash函数,具有较好的分布特性。另外,Pearson's Hash和CRC Hashing也是常见的Hash算法,虽然未在给定的代码中完全展示,但它们分别...

    哈希表搜索算法介绍和java代码实现

    下面是一个简单的Java实现哈希表搜索的示例: ```java import java.util.HashMap; public class HashTableSearch { public static void main(String[] args) { // 创建哈希表 HashMap, String&gt; hashtable = new...

    数据加密MD5(包括javascript代码和java代码实现的两种方式)

    以下是一个简单的Java代码示例: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Example { public static void main(String[] args) { String ...

    JAVA上百实例源码以及开源项目源代码

    Java源代码实现部分,比较有意思,也具参考性。像坐标控制、旋转矩阵、定时器、生成图像、数据初始化、矩阵乘法、坐标旋转、判断是否是顺时针方向排列、鼠标按下、放开时的动作等,都可在本源码中得以体现。 Java...

    geohash算法mysql版代码

    网上有很多geohash算法的实现,都是基于java或者php代码实现的,没有sql实现的版本,这里使用mysql简单实现了这个算法

    哈希表java实现及简单演示

    在Java的HashMap中,哈希函数是由内部的`hash()`方法提供的,它通过计算键对象的哈希值并进行位操作来确定元素的位置。如果两个不同的键产生了相同的哈希值,那么就会发生冲突。 处理冲突有多种策略,如开放寻址法...

    java代码性能优化23种技巧

    ### Java代码性能优化23种技巧详解 #### 一、避免在循环条件中使用复杂表达式 在Java中,尤其是在不进行编译器优化的情况下,循环条件会在每次迭代时都被重新计算。如果循环条件涉及复杂的表达式或者动态计算,这...

    uthash开源的hash函数实现

    UTHASH 是一个开源的 C 语言库,提供了一种简单且高效的哈希表实现,用于在 C 代码中快速查找和管理数据结构。这个库的主要功能是提供一个宏定义的集合,可以方便地将结构体转化为哈希表,进而进行添加、删除、查找...

    一个java加密程序源代码

    除了这些基础加密操作,源代码可能还包含了一些安全实践,例如使用随机数生成器(java.security.SecureRandom)来生成加密所需的随机数据,或者实现加密算法的模式,如CBC(Cipher Block Chaining)或CFB(Cipher ...

    java-Hash算法大全.doc

    本文将对 Java 中的哈希算法进行详细的介绍,包括加法哈希、旋转哈希、一次一个哈希、Bernstein 哈希、Pearson 哈希、CRC 哈希、Universal 哈希等七种哈希算法的实现和原理。 一、加法哈希(Additive Hash) 加法...

    MD5Util_newspaper4pi_java_哈希值_MD5Util获取hash_

    标签"java 哈希值 MD5Util获取hash"进一步强调了这个工具类是用Java语言实现的,主要功能是计算哈希值,特别是MD5哈希值,而`MD5Util获取hash`可能是指`MD5Util`类中用于计算哈希的具体方法。 在提供的压缩包文件...

    如何找到周围8个区域的GeoHash编码

    5. **代码实现提示**: - 你可以创建一个方法,接收一个GeoHash编码作为输入,然后返回其周围的8个邻居编码。 - 使用位运算符来高效地修改GeoHash编码的最后一位。 - 注意边界条件,确保修改后的编码仍然是有效的...

    java实现的bt协议项目源码ttorrent,非常不错的

    【Java实现的BT协议项目源码ttorrent详解】 在IT领域,P2P(Peer-to-Peer)网络技术因其高效、分布式的特点而受到广泛关注,其中BitTorrent(简称BT)协议是P2P网络中用于文件分发的一种流行协议。本文将深入探讨一...

    java实现memcache服务器的示例代码

    Java 实现 Memcache 服务器的示例代码 Memcache 是一个高性能的分布式内存对象缓存...代码实现这里贴图功能出了点问题,可以去文末我的项目地址查看类图。这里采用了指令模式和工厂模式实现指令的创建和执行的解耦。

    GeoHash是目前比较主流实现位置服务的技术,用最简洁的Java实现GeoHash算法.zip

    跨平台性(Write Once, Run Anywhere): Java的代码可以在不同的平台上运行,只需编写一次代码,就可以在任何支持Java的设备上执行。这得益于Java虚拟机(JVM),它充当了代码和底层硬件之间的中介。 面向对象: ...

    hash算法相关介绍

    ### Hash算法相关介绍 在计算机科学领域,哈希(Hash)是一种将任意长度的数据映射为固定长度数据的技术。哈希算法广泛应用于多种场景中,包括但不限于数据完整性验证、密码存储、快速查找等。本文主要介绍了几种...

    java2登录窗口原代码+数据库

    3. **事件处理**:当用户点击登录按钮时,Java代码会监听这个事件并触发相应的处理函数。在这里,代码会读取用户输入的用户名和密码,然后执行验证逻辑。 4. **数据库交互**:为了存储和验证用户凭据,应用需要连接...

    java注册与登录功能源代码带数据库

    以上是关于"java注册与登录功能源代码带数据库"的详细解析,这个源代码实例可以帮助初学者理解如何在Java环境中实现用户管理功能,并与数据库进行交互。对于开发者来说,这是一个学习和实践的好素材。

Global site tag (gtag.js) - Google Analytics