`

开散列的简单模拟(一)

 
阅读更多
1. 散列

   散列有两种形式。一种是开散列(或外部散列),它将字典元素存放在一个潜无穷的空间里,因此它能处理任意大小的集合。
另一种是闭散列(或内部散列), 它使用一个固定大小的存储空间,因此它能处理的集合的大小不能超过它的存储空间的大小。

2. 开散列

   (1)下图是一个开散列表,它表示了开散列的基本数据结构。

     


   (2) 基本思想

       开散列的基本思想是将集合的元素(可能有无穷多个)划分成有穷多个类。例如,划分为0、1、2、....、B-1这B个类。用散列函数h将集合中的每个元素x映射到0、1、2、....、B-1之一,h(x)的值就是x所属的类。h(x)称为x的散列值。上面所说的每一个类称为一个桶,并且称x属于桶h(x).

       我们用一个链接表表示一个桶。x是将第i个链接表中的元素当且仅当h(x)=i,即x属于第i个桶。B个桶(链接表)的桶(表)头存放于桶(表)头数组中。


       用散列表来存储集合中的元素时,总希望将集合中的元素均匀地散列到每一个桶中,使得当集合中含有n个元素时,每个桶中平均有n/B个元素。如果我们能估计出n,并选择B与n差不多大小时,则每个桶中平均只有一两个元素。这样,字典的每个运算所需要的平均时间就是一个与n和B无关的小常数。由此可以看出,开散列表是将数组和链接表结合在一起的一种数据结构,并希望能利用它们各自的优点且克服它们各自的缺点。因此,如何选择随机的散列函数,使它能将集合中的元素均匀地散列到各个桶中是散列技术的一个关键。

  (3) 求余运算。

       如果x是不是数值型,将字符串x中的每个字符转换成一个整数,然后将字符串每个字符所对应的整数相加,用和除以B的余数作为h(x)的值,显然这个余数是0、1、2、....、B-1之一。

3. 模拟代码:

package boke.dictionary;
/**
 * 开散列的简单模拟(一): 桶元素
 * 
 * @since jdk1.6
 * @author 毛正吉
 * @version 1.0
 * @date 2010.05.25
 * 
 */
public class Node {
	public int iData;
	public Node next;
	
	public Node(int i) {
		iData = i;
	}
}

-----------------------------------------------

package boke.dictionary;

/**
 * 开散列的简单模拟(一): 作为简单模拟,元素选取整型
 * 
 * @since jdk1.6
 * @author 毛正吉
 * @version 1.0
 * @date 2010.05.25
 * 
 */
public class Hash {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Hash hh = new Hash(1000);
		for (int i = 0; i <= 100; i++) {
			hh.insert(i);
		}
		System.out.println(hh.find(10));
		System.out.println(hh.find(50));
		System.out.println(hh.find(90));
		System.out.println(hh.find(1000));

		hh.insert(1000);
		System.out.println(hh.find(1000));

		hh.delete(10);
		System.out.println(hh.find(10));

		hh.insert(0);
		System.out.println(hh.find(0));

	}

	private Node[] bucket; // 桶
	private int maxSize; // 桶的个数

	/**
	 * 构造方法
	 * 
	 * @param maxSize
	 */
	public Hash(int maxSize) {
		this.maxSize = maxSize;
		bucket = new Node[maxSize];
		makeNULL();
	}

	/**
	 * 字典初始化
	 */
	public void makeNULL() {
		for (int i = 0; i < maxSize - 1; i++) {
			bucket[i] = null;
		}
	}

	/**
	 * 查找x是否在字典中
	 * 
	 * @param x
	 * @return
	 */
	public boolean find(int x) {
		int mod = x % maxSize;
		Node current = bucket[mod];

		while (current != null) {
			if (current.iData == x) {
				return true;
			} else {
				current = current.next;
			}
		}

		return false;
	}

	/**
	 * 插入x到hash字典中
	 * 
	 * @param x
	 */
	public void insert(int x) {
		if (!find(x)) {
			Node node = new Node(x);
			int mod = x % maxSize;

			Node old = bucket[mod];
			bucket[mod] = node;
			bucket[mod].next = old;
		} else {
			System.out.println("该值已存在,不能重复插入!");
		}
	}

	/**
	 * 从hash字典中删除x
	 * 
	 * @param x
	 */
	public void delete(int x) {
		int mod = x % maxSize;

		if (bucket[mod] != null) {
			if (bucket[mod].iData == x) {
				bucket[mod] = bucket[mod].next;
			} else {
				Node current = bucket[mod];
				while (current.next != null) {
					if (current.next.iData == x) {
						current.next = current.next.next;
					} else {
						current = current.next;
					}
				}
			}
		}
	}

}
      
  • 大小: 30.5 KB
分享到:
评论
4 楼 maozj 2010-06-28  
wese345 写道
大学时,数据结构对我来所简直是噩梦啊,呵呵

--------------
呵呵 算法是计算机科学的灵魂 基础更为重要
3 楼 wese345 2010-06-28  
大学时,数据结构对我来所简直是噩梦啊,呵呵
2 楼 maozj 2010-06-28  
mccxj 写道
最基本的数据结构,没看到什么亮点


你能给出闭散列的代码吗?在30分钟内
1 楼 mccxj 2010-06-28  
最基本的数据结构,没看到什么亮点

相关推荐

    大学数据结构模拟试卷一到八

    4. **散列与查找**:散列是一种快速查找技术,通过散列函数将关键字映射到数组中。冲突解决方法如开放寻址法和链地址法也是重要知识点。 5. **排序算法**:包括冒泡排序、选择排序、插入排序、快速排序、归并排序、...

    java模拟QQ,图形化界面版

    在本项目中,开发者使用Java语言实现了一个人工模拟的QQ应用程序,主要目的是为了学习和实践。这个图形化界面版的模拟QQ具备了基础的登录、注册和聊天功能,虽然它是一个单机版,但仍然提供了丰富的学习素材。下面将...

    线性开型寻址 单步演示软件

    线性开型寻址是一种哈希表的冲突解决方法,主要应用于数据存储和查找的高效实现。在数据结构课程中,这种技术是重要的学习内容,因为它可以提高数据存取的速度,尤其是在处理大量数据时。本软件是山东大学数据结构...

    实验三 存储管理实验.doc

    - **指令地址流**:实验要求生成一个混合的指令地址流,包含50%的顺序执行、25%的前部散列和25%的后部散列,以模拟不同执行模式下的页面访问。 2. 固定式分区分配的存储管理: 在固定式分区分配中,内存被预先划分...

    基于java的万有引力模拟程序

    1,散列星空:不同大小的星体被中心黑洞吸引,形成一个小型的星系。在此过程中会出现双星、聚星、星团等现象。黄道视角定位在随机星体上。 2,太阳系(可操控):模拟太阳系六大行星(只到土星轨道)和众多小行星的...

    数据结构试题集(考研真题 模拟题)

    二叉树是最简单的一种,每个节点最多有两个子节点。AVL树和红黑树是自平衡的二叉搜索树,确保了查找、插入和删除操作的时间复杂度为O(logn)。堆是一种特殊的树形结构,通常用于实现优先队列。Trie字典树常用于字符串...

    RSA数字签名算法的模拟实现.doc

    本文档主要介绍了一个简易版的RSA数字签名算法的模拟实现过程,用于加密和验证文件内容。 首先,RSA算法的核心在于两个大素数p和q的乘积n,以及与n相关的欧拉函数φ(n)。通过计算p和q的欧拉函数,可以得到模逆元e和...

    2022年计算机等级考试四级模拟试题.doc

    全国计算机等级考试四级模拟试题主要涵盖计算机硬件、软件、数据结构、算法以及操作系统等多个方面的知识。以下是根据题目内容解析的一些重要知识点: 1. **程序计数器**:在计算机体系结构中,程序计数器(PC)是...

    数据结构模拟试卷(c语言版)

    ### 数据结构模拟试卷知识点解析 #### 一、单项选择题解析 **1.1 题目:** 以下数据结构中哪一个是线性结构? - **选项:** A.有向图 B.队列 C.线索二叉树 D.B树 - **答案:** B.队列 - **解析:** 在数据结构中,...

    模拟ATM

    ATM(Automated Teller Machine)模拟程序是一个常见的Java编程练习,它可以帮助学习者掌握面向对象编程、控制流、异常处理、数据存储等关键概念。在这个项目中,我们将深入探讨如何构建一个简单的ATM系统,它包括...

    操作系统 文件操作的模拟实验报告(报告中附源码)

    本次实验旨在通过实践操作加深学生对于文件系统原理的理解,以及如何利用高级编程语言来模拟实现一个简易的文件管理系统。通过这一过程,可以帮助学生更好地掌握文件管理的核心概念,如文件的逻辑结构、存储结构及其...

    四级数据库工程师笔试模拟试题(5).

    全国计算机等级考试四级数据库工程师笔试模拟试题(5)是一份针对数据库工程师的考试练习,包含多项选择题,涵盖了计算机基础知识、数据结构、操作系统、数据库管理等多个方面。以下是这些题目涉及的知识点详解: 1. ...

    字符串处理算法

    开散列通过在冲突位置建立链表来解决问题,而闭散列则通过移动到哈希表的下一个位置。Rabin-Karp算法是Hash算法在字符串处理中的一个典型应用,它利用了字符串和k进制数的对应关系来实现快速字符串匹配。Rabin-Karp...

    05年4月份三级数据库模拟试题

    18. 数据结构特性:栈是先进后出(FILO),二叉树的第i层最多有2^(i-1)个节点,深度为k的完全二叉树最多有2^k - 1个节点,线性结构和链式结构各有优缺点,不能简单比较。 19. 快速排序趟数:对于给定序列,快速排序...

    哈尔滨工业大学数据结构与算法模拟题.doc

    开放寻址法是减少冲突的一种方法,而直接取模是最简单的散列函数构造方法。 7. 线性表的存储结构:线性表可以使用数组、链表或者双向链表来实现。 二、回答问题部分涉及了树的性质、栈的操作、数据结构与抽象数据...

    mocki:简单节点服务器模拟资源api的主干json响应

    也许有一天,mocki会长大,接受方便的选项,例如仅提供操作的路由散列... 或者可能只是保留一个乐于遵循简单约定的小脚本。 mocki比的凉爽度少1/1000,但是我想要坚持不懈并学习一些东西。 用法 为集合创建目录以...

Global site tag (gtag.js) - Google Analytics