数据处理入门—自定义Hash结构(超详细!!!)

数据处理入门—自定义Hash结构(超详细!!!)
在蓝杰学JAVA有一段时间了,对于前端时间的学习,我不能全盘否定。但是我真的觉得没学到多少知识。对于那种搭积木式的学习产生厌倦了。我想也许一段过渡过程吧,以后的学习应该迈向一个新的台阶!算法和数据结构是软件工程中的核心,这才是精华所在,这也是我目前最薄弱,最有待加强学习的地方。做为IT工程师,必须要有超强的对数据的分析处理能力和对信号的分析处理能力。这将是我以后学习方向的重点。
下面开始讲我的HashSet结构吧。
关键技术点分析
结构由数组加链表组成,简称:挂链式。在我看来是一种不错数据结构。
通过HashCode()函数,定义自己的Hash()函数。给存储储存对象在数组上分配索引值。这里再补充一下:HashCode(),
通过递归搜索,进行添加、读取、删除操作。刚开始写的时候,此技术点成为了我的难点。
,进行reHash()处理,这里涉及到阈值的设定,均衡度等概念。
全面分析与总结
1.自定义节点,并创建一个数组和相关属性设定。
我们用的结构是数组+链表。我对此的理解是,对数据快,进行分块处理操作,分成了数组长度的减一个小数据快。以便我们查找,管理等操作。
A.自定义节点类
package MyHashSet3;
//自定义节点类
public class Node {
private Object Node;// 节点的值
private Node nextNode;
public Node(Object Node){
this.Node=Node;
}
public void setNextNode(Node nextNode ){
this.nextNode=nextNode;//指向下一个节点对象
}
public Object getNode() {
return Node;
}
public Node getnextNode() {
return nextNode;
}

}


B.创建数组,阈值等属性设定。
public class MyHashSet {
private Node[] NodeArry;//定义一个节点型数组。用于挂链
private int count;//元素个数
private int Threshold;//阈值,用于对于存储空间结构冲突上限进行判定。
private int Thresholdlimit=8;//阈值上限,在添加元素的时候进行阈值判定操作
private static int arryLength;
//调用构造方法,并自定义数组长度
public MyHashSet(int length){
NodeArry=new Node[length];//创建节点型数组
arryLength=length;
if(arryLength>=0){
Threshold=count/arryLength;//初始化阈值
}else{
System.out.println("数组长度设置错误,数组长度必须大于零!");
}
}


结构已经构造成功,现在进行相关处理操作。
C.自定义Hash()。
//自定义哈希函数
private static int hash(Object o){
int address =o.hashCode();//取得目标对象的物理内存地址
int h=address%arryLength;//根据数组长度进行取模运算
return h&(arryLength-1);//保证返回的哈希值为,为数组范围的数。
}

D.定义添加、读取、删除等方法。这里重要的技术点是运用递归搜索。下面是我定义的添加元素的方法。
/*
* 添加新元素的方法,即更新元素的方法
*/
public void updateNode(Object node){
if(Threshold //通过哈希取模运算得到,将要放入数组元素的索引位置
int index = hash(node);
//首先我们创建一个将要放入的节点
Node newNode = new Node(node);
//得到数组将要放入位置的元素,用于判断。
Node currentNode =NodeArry[index]; //在这里强调逻辑一定要严密!!!
//对数组进行元素判定,按条件储存
if(currentNode==null){//如果当前数组为空,或者存在但不相等则放入新的数组
NodeArry[index]=newNode;
count++;//元素加一操作。
}
else{
Node nextNode;
//下面进行递归搜索,查找链表中为空的节点,并添加新元素。
while(!currentNode.getNode().equals(node)&&(nextNode=currentNode.getnextNode())!=null){
currentNode=nextNode;//添加条件不满足就继续搜索,直到找到满足的添加条件为止。
//当满足添加条件时,自动循环结束,进行添加操作。
}
if(!currentNode.getNode().equals(node)&¤tNode.getnextNode()==null){
currentNode.setNextNode(newNode);//给满足添加条件的位置添加节点。
count++;//元素加一操作。
}

}
}else{//超过规定阈值了,重新构造存储空间
reHash();
System.out.println("重新构造了空间结构!,请根据的您的需求,是否选择合适的存储空间结构!");
}

}

E.定义完结构的相关处理方法后,最后一步就是进行reHash()处理了。也就是当结构中的冲突十分的严重,超过了指定阈值的时候进行存储结构的重构操作。我是在每一下添加新元素的时候,进行阈值判定处理。
public void reHash(){
//对当前数据存储数组进行扩容处理
NodeArry=new Node[2*arryLength];//对当前数据存储数组进行扩容处理
//取得扩容前的所有元素数组
Object[] oldArrayNode =getAll();
//重新分配元素
for(int i=0;i updateNode(oldArrayNode[i]);//重新逐一添加元素,将就空间结构元素重新均匀分配给扩容后的新空间
}

}

/*
* 取得所有元素的方法
*/
public Object[]getAll(){
Object[] allNode = new Object[count];//创建一个目标数组用来,接收取得的元素
int index =0;
for(int i=0;i //取得每个位置的头结点,对链表进行遍历
Node currentNode=NodeArry[i];
while(currentNode!=null){
allNode[index++]=currentNode.getNode();
currentNode=currentNode.getnextNode();//若循环条件满足,递归遍历继续取得数据
}
}
return allNode;//返回取得元素的数组
}


F.到这里我们差不多,也就写完一个简单的HashSet了。
最后我们进行CURD测试。
下面是我测试的结果,结果似乎不令人满意啊。

[img]http://dl.iteye.com/upload/attachment/0064/5883/ccee5735-f57f-3a3a-9a2e-10d1ed68bd26.jpg[/img]

G.心得感悟
虽然结果,不怎么令人满意,但这是个开始吧。使认识到数据处理的重要性,还有逻辑一定要严密,思路与条理都清晰,对每一个概念,都要去刨根问底的弄得十分清楚,这样才会事半功倍,还有很久没写博客了,这里我真的认识到学博客真的很重要。不论是菜鸟还是大牛,博客必不可少!

你可能感兴趣的:(学习总结,数据结构,Hash,递归搜索,数据处理)