`

由hash结构,看数据结构优化“宗法”

阅读更多
 

     俗话说:“万变不离其宗”,程序亦是如此。

       无论是 HashSet HashMap Hashtable ,还是 TreeSet PriorityQueue ,都不离其原则。众所周知,衡量一个程序的好坏、数据结构好坏的重要指标是其空间复杂度和时间复杂度。

“鱼和熊掌不可兼得”,时间复杂度和空间复杂度也不能兼顾。比如数组,由于存储空间物理上不连续,其空间占用大;而链表,虽然占用空间较小,而且可以充分利用零散的存储空间,但它没有数组所拥有的下标,导致其时间复杂度较高。

      万事万物都有其制约因素,所以也就没有完全意义上的完美,但我们可以寻求“相对的完美”。时间复杂度和空间复杂度势必有一方要被舍弃,但高速发展的社会不仅要求时间上的高效,也要求空间上的资源高效利用。看官(应该有)要问了,“那怎么办呀”?

      我们聪明的老祖宗已经为我们埋下了伏笔。“中庸”的思想帮到了我们。既然各有优点,那何不有机的结合各种结构的优点,这样不就可以达到时间复杂度和空间复杂度的平衡点,也许会是黄金分割点。 TreeSet 就是个鲜明的例子,是 tree 结构和 Set 结构的有机结合,极大的提高了数据结构的“优雅”和“韵律”。

      看到这,你也许以为,“有机结合各家所长”就是“宗”了。非也,宗者,乃假外物以为余是也。借助外力补足缺点才是王道。有机结合是通过结合利用其它结构补足自身补足。

除此之外,通过适当的转换,也可以达到优化结构的目的。高中物理书中写道:“力是改变物体状态的原因”。对于 IT 男男女女来说,我们想要改变现有对象的状态时,添加方法就是我们的“力”。你没有下标,增加了时间复杂度。 Ok ,我将你跟连续的下标联系起来不就行啦!以 hash 结构为例,基本思想就是通过 hash 函数(即我们的“力”),改变原有的数据结构特点,以补不足。显然, HashSet 就是用 hash 函数构造的 Set HashMap 就是用 hash 函数构造的 Map ……你若问我 hash 函数是什么?它是具体情况而定。

    下面,以我自定义的 hash 结构为例。

    构建一个简单的 hash 结构,流程如下:

1、  利用 hash 函数得到 hash 值,通常为键值或下标位置。

2、  将对应的属性值放入到对应键值或下标的相应位置。如选择的是键值对就放入集合内;如选择的是链表就放入节点,加在末尾如下图 1

3、  因为是通过函数计算,且键值和下标的本地 hashcode 值通过计算可能相同,就会产生冲突,链表可以加在末尾,但随冲突的增加,链表越来越长,采用 hash 结构的优势越来越弱,此时就要重构 hash 结构。是否需要重构根据具体情况而设定的峰值而定。如下图 2 ,为 rehash 后的结果。

4、  于是出现了问题出现了,怎样重构更好呢? hash 结构其实是通过 hash 函数对各个属性值的散列。既然是散列,就会有一个散列的程度问题。重构时,如能使当前结构内数据 rehash 后,其散列程度趋于 0 时,重构效果较好。统计学可以通过计算残差,判断之前的系统是否稳定,相信对于 hash 结构,同样适用。散列程度的值可以根据冲突数与总数据量之间的关系得到。如下图 3

图1:



 图2:



 图3:


我的代码示例如下:

Hashstructure

package hash;

import java.util.LinkedList;

public class HashStruct {
	// 定义一个数组
	private static int hashcode = 10;// hashcode值用于rehash时,重构hash结构
	private static LinkedList[] hasharray;
	private static int clashes;// 记录冲突数
	private static int numbers;// 记录结构内成员数

	// hash结构就是根据当前数值,通过hash函数,算得当前值应放入的hashstructure中的位置。
	// 设计hash函数
	public int hashFunction(int x) {
		int hash = x % hashcode;// hashcode为构建的hash函数中的一个变量
		return hash;
	}

	// 向hash结构中添加元素
	public void add(int key) {
		int index = this.hashFunction(key);
		if (hasharray[index].size()>0) {
			clashes++;
		}
		hasharray[index].add(key);

		numbers++;
		// 判断添加后冲突数是否超过峰值,如超过,重构hash结构
		if (this.rank(clashes, numbers)) {
			this.rehash(hasharray);
		}
	}

	// 当冲突数超过峰值时,需要重建hash结构
	public void rehash(LinkedList[] hasharray) {
		hashcode += 5;
		LinkedList[] hasharray2 = hasharray.clone();
		hasharray = null;
		this.init();
		for (int i = 0; i < 10; i++) {
			for (int j = 0; j < hasharray2[i].size(); j++) {
				this.add(hasharray2[i].get(j).hashCode());
			}
		}
		System.out.println("rehashed!");
	}

	// 峰值计算函数
	public boolean rank(int clash, int numbers) {
		boolean result = false;
		double c=(double) clash / (double) numbers;
		if (((double) clash / (double) numbers) >= 0.65) {
			result = true;
		}
		return result;
	}

	// 遍历对应hash值下的元素
	public void get() {
		for (int i = 0; i < hasharray.length; i++) {
			System.out.println("hasharray["+i+"]:"+hasharray[i]);
		}
	}

	// 初始化hashstruct
	public void init() {
		hasharray = new LinkedList[hashcode];
		clashes = 0;// 记录冲突数
		numbers = 0;// 记录结构内成员数
		for (int i = 0; i < hashcode; i++) {
			hasharray[i] = new LinkedList<Integer>();
		}
	}
}
 

Test

 

package hash;

public class Test {
	public static void main(String[] args) {
		HashStruct hs = new HashStruct();
		hs.init();
		// 添加10个数
		hs.add(10);
		hs.add(12);
		hs.add(22);
		hs.add(25);
		hs.add(15);
		hs.add(35);
		hs.add(27);
		hs.add(37);
		hs.add(47);
		hs.add(17);
		// 检查添加结果
			hs.get();

		//继续添加,验证rehash
		for(int i=1;i<20;i++){
			hs.add(i*7);
		}
		hs.get();
		
	}
}
 

 

图4:

  如上图 4 为输出结果。对比上图 1 和图 2 ,达到了 rehash 的效果。(蓝色线上是初始构建 hash 结构的测试,下方是 rehash 测试。注意红色标记为初始时插入测试的数据。)

       Array AND LinkedList Hashstructure 雌雄双剑剑法演示完毕,请各位看官出招。

  • 大小: 13 KB
  • 大小: 16.7 KB
  • 大小: 17.8 KB
  • 大小: 13.8 KB
3
0
分享到:
评论

相关推荐

    数据结构课程设计hash表

    哈希表,又称散列表,是数据结构课程中一种高效的数据组织方式,它通过特定的函数(哈希函数)将键(key)映射到数组的特定位置来实现快速访问。这种数据结构允许我们以接近常数时间的复杂度进行插入、删除和查找...

    上海交大数据结构课件 上海交大数据结构课件

    此外,哈希表(Hash Table)是另一种重要的数据结构,它通过散列函数实现快速的查找、插入和删除操作,达到近乎恒定的时间复杂度。而堆(Heap)是一种特殊的树形数据结构,通常用于实现优先队列,例如在排序算法(如...

    数据结构课后答案.pdf

    7. **哈希表(Hash Table)**:哈希表是一种通过哈希函数来实现快速查找的数据结构,它允许将键映射到特定的位置以存储数据,从而实现平均时间复杂度为O(1)的查找性能。冲突解决策略包括链地址法、开放寻址法等。 ...

    图形化hash函数 数据结构

    在数据结构中,哈希表(Hash Table)是利用哈希函数实现的一种高效查找数据结构。它通过将键(Key)映射到数组的索引位置来存储和检索数据,这大大减少了查找的时间复杂度,通常可以达到平均O(1)的时间复杂度。 本...

    广工计算机数据结构课程设计之电梯模拟

    此外,项目报告可能会包括以下部分:电梯模型的介绍、数据结构的选择与实现、算法设计与分析、系统功能展示、性能测试与优化以及可能存在的问题和改进方案。通过这样的课程设计,学生能深入理解数据结构的实际应用,...

    清华大学教程 --数据结构

    此外,哈希表(Hash Table)是一种提供快速查找的数据结构,通过散列函数将键映射到数组的特定位置,实现常数时间的查找。堆(Heap)是一种特殊的树形数据结构,通常用于实现优先队列,如最大堆和最小堆。 排序算法...

    李春葆数据结构教程上机实验全部源代码

    数据结构是计算机科学中的核心课程,它探讨了如何有效地存储和检索数据,是软件工程、算法分析和计算机系统设计的基础。李春葆教授的《数据结构教程》是该领域的经典教材,深受学生和专业人士的喜爱。这个压缩包包含...

    "动态规划:数据结构中的优化艺术"

    5. **哈希表**(Hash Table):通过键值对存储数据的数据结构,可以快速地通过键来访问数据。 6. **树**(Tree):一种层次结构的数据结构,每个节点有零个或多个子节点,通常用于表示具有层次关系的数据。 7. **图*...

    数据结构 课件java版本

    数据结构是计算机科学中的核心课程,它探讨了如何在计算机中有效地存储和处理数据,以优化算法的性能。本课件“数据结构 课件java版本”是基于Java编程语言来讲解这一主题的,旨在帮助学生和开发者深入理解数据结构...

    数据结构_北大

    8. **实践应用**:结合实际问题,讲解如何选择合适的数据结构以及优化数据结构设计,提升程序性能。 这些PPT文件的命名方式表明,它们可能按照教学进度或主题进行了分类,例如“数据结构02.ppt”可能涵盖第二部分的...

    数据结构1800题 很全的数据结构题库虽然老但是经典

    数据结构是计算机科学中的核心课程,它探讨了如何在计算机中高效地组织和管理数据,以便于进行快速的检索、存储和操作。本题库“数据结构1800题”虽年代较远,但其经典性使得它仍然对学习者具有很高的参考价值。Word...

    数据结构(c语言版)课后题答案-(学生版 )

    C语言版的数据结构教材,由严蔚敏教授编著的《数据结构》(第2版),是许多大学和考研机构推荐的经典教材。该书深入浅出地介绍了各种基本的数据结构类型,如线性表、栈、队列、树、图以及查找和排序算法。配合课后...

    Java数据结构和算法中文第二版

    2. **链表(Linked List)**:链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。 3. **栈(Stack)**:栈是一种特殊的线性数据结构,遵循后进先出(LIFO)原则。 4. **队列(Queue)**...

    数据结构和算法-思维导图.pdf

    在数据结构和算法领域中,存在大量不同的概念和术语,这些都构成了计算机科学的基础。思维导图是一种有效的方式来组织和回顾这些概念,通过可视化方式帮助记忆和理解。从提供的文件【标题】:"数据结构和算法-思维...

    数据结构课程实验Hash表设计实验报告

    数据结构课程实验中,哈希表的设计与实现是一项重要的任务,旨在帮助学生深入理解哈希表的概念和工作原理。哈希表是一种数据结构,通过哈希函数将数据映射到一个固定大小的数组中,以实现快速的查找、插入和删除操作...

    《数据结构与算法分析》.txt

    基本数据结构 基本数据结构部分包括线性表、堆栈与队列、数组、字符串、整数集合类、树(包括AVL树、伸展树等)、图(包括网络流等问题的讨论)、散列(Hash)等 典型算法 典型算法部分主要介绍了若干典型算法的实现...

    软考之数据结构

    《软考之数据结构》是针对软件设计师考试中关于数据结构这一重要知识点的详细解析。在计算机科学领域,数据结构是研究数据如何在计算机中存储和操作的基础理论,它是算法设计与分析的重要支撑。本资料集包含了多个...

Global site tag (gtag.js) - Google Analytics