哈希表-线性探测
2016-11-28 11:41
323 查看
哈希表是一种数据结构,它可以提供快速的插入和查找操作。不论哈希表有多少数据,插入和删除(有时包括删除)只需要接近常量的时间,即O(1)的时间级。
哈希表运算非常快,在计算机程序中,如果需要在一秒钟内查找上千条记录,通常使用哈希表,哈希表的速度明显是树快。
哈希表也有一些缺点:它是基于数组的,数组创建后难于扩展。某些哈希表基本被填满时,性能下降非常严重,所以程序员必须要清楚表中将要存储多少数据。并且,也没有一种简便的方法可以以任何一种顺序遍历表中的数据项,如果需要这种能力,就只能选择其他数据结构。如果需要这种能力,就需要选择其他数据结构。然而,如果不需要有序遍历数据,并且可以提前预测数据量的大小,那么哈希表在速度和易用性方面是无与伦比的。
——————————————————————————————————————
开放地址法–方法1–线性探测
在线性探测中,线性的查找空白单元。如果5421是要插入数据的位置,它已经被占用了,那么就使用5422,然后是5423,依次类推,数组下标一直递增,直到找到空位,这就叫做线性探测,因为它沿着数组下标一步一步顺序的查找空白单元。
哈希表运算非常快,在计算机程序中,如果需要在一秒钟内查找上千条记录,通常使用哈希表,哈希表的速度明显是树快。
哈希表也有一些缺点:它是基于数组的,数组创建后难于扩展。某些哈希表基本被填满时,性能下降非常严重,所以程序员必须要清楚表中将要存储多少数据。并且,也没有一种简便的方法可以以任何一种顺序遍历表中的数据项,如果需要这种能力,就只能选择其他数据结构。如果需要这种能力,就需要选择其他数据结构。然而,如果不需要有序遍历数据,并且可以提前预测数据量的大小,那么哈希表在速度和易用性方面是无与伦比的。
——————————————————————————————————————
开放地址法–方法1–线性探测
在线性探测中,线性的查找空白单元。如果5421是要插入数据的位置,它已经被占用了,那么就使用5422,然后是5423,依次类推,数组下标一直递增,直到找到空位,这就叫做线性探测,因为它沿着数组下标一步一步顺序的查找空白单元。
package com.hash; import java.io.BufferedReader; import java.io.InputStreamReader; class DataItem { private int iData; //................... public DataItem(int ii) { iData = ii; } //............. public int getKey() { return iData; } } class HashTable { private DataItem[] hashArray; private int arraySize; private DataItem nonItem; //for deleted items //..................... public HashTable(int size) { arraySize = size; hashArray =new DataItem[arraySize]; nonItem = new DataItem(-1); //deleted item key is -1 } //................ public void displayTable() { System.out.println("Table:"); for (int i = 0; i < arraySize; i++) { if(hashArray[i] != null) System.out.println(hashArray[i].getKey()+""); else System.out.println(""); } System.out.println(""); } //............................. public int hashFunc(int key) { return key % arraySize; //哈希函数 } //.......................... public void insert(DataItem item) //假设哈希表没有 { int key = item.getKey(); int hashVal = hashFunc(key); while(hashArray[hashVal] != null&& hashArray[hashVal].getKey() != -1) { ++ hashVal; //go to next cell hashVal %= arraySize; } hashArray[hashVal] = item; } //................................ public DataItem delete(int key) { int hashVal = hashFunc(key); while(hashArray[hashVal] != null) { if(hashArray[hashVal].getKey() == key) { DataItem temp = hashArray[hashVal]; //用特殊的数据项nonItem 覆盖原来的数据,这个变量事先定义为-1 hashArray[hashVal] = nonItem; return temp; } ++hashVal; hashVal %= arraySize; } return null; } /* * find()方法首先调用hashFunc()方法把待查找关键字转换成数组下标hashVal。 * hashFunc()方法把%操作符应用于查找关键字和数组容量。 * 接着,在while循环中,find()方法检查这个下标所指单元是否为空(null) 。如果不为空, * 他会检查这个数据项是否包含待检查关键字,如果包含,find()方法返回这个数据项 * 如果不包含,find()递增hashVal,并且回到while循环的开始,检查下一个单元是否被占用。 */ public DataItem find(int key) { int hashVal = hashFunc(key); while(hashArray[hashVal] != null) { if(hashArray[hashVal].getKey() == key) return hashArray[hashVal]; ++hashVal; hashVal %= arraySize; } return null; } //............................... } class HashTableApp { public static void main(String[] args) throws Exception { DataItem aDataItem; //变量keyPerCell指定了关键字范围的比率,它是以数组大小为基础的。如果指定表长为20,那么关键字从0到200 int aKey,size,n,keysPerCell; System.out.print("Enter size of hash table:"); size = getInt(); System.out.print("Enetr initial number of items:"); n=getInt(); keysPerCell = 10; HashTable theHashTable = new HashTable(size); for (int i = 0; i < n; i++) { aKey = (int)(java.lang.Math.random() * keysPerCell*size); aDataItem =new DataItem(aKey); theHashTable.insert(aDataItem); } while(true) { System.out.print("Enter firdt letter of"); System.out.print("show,insert,delete,or find:"); char choice = getChar(); switch(choice) { case 's': theHashTable.displayTable(); break; case 'i': System.out.print("Enter key value to insert:"); aKey = getInt(); aDataItem = new DataItem(aKey); theHashTable.insert(aDataItem); break; case 'd': System.out.print("Enter key valu bbaa e to delete:"); aKey = getInt(); theHashTable.delete(aKey); break; case 'f': System.out.println("Enter key value to find:"); aKey = getInt(); aDataItem = theHashTable.find(aKey); if(aDataItem != null) { System.out.println("found"+aKey); } else System.out.println("Could not find"+aKey); break; default: System.out.print("Invalid enery\n"); } } } //....................... public static String getString() throws Exception { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = br.readLine(); return s; } //......................... public static char getChar() throws Exception { String s= getString(); return s.charAt(0); } //............... public static int getInt() throws Exception { String s= getString(); return Integer.parseInt(s); } }
相关文章推荐
- 数据结构实验之查找七:线性之哈希表(线性探测解决哈希表的冲突)
- 线性探测法构造哈希表(hash)
- 哈希表 除数余留 + 链地址 && 线性探测 && 平方探测
- 哈希表线性探测&二次探测
- 哈希表(开放寻址,线性探测)
- 哈希表开放寻址法之线性探测法解决冲突问题
- 线性探测法构造哈希表(hash)
- 哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度
- 线性探测法构造哈希表(hash)
- 【数据结构】哈希表(线性探测法)
- 哈希表(线性探测再散列)
- 哈希表-开放地址法之线性探测代码(JAVA)
- 哈希表的构造之线性探测法
- 【除留余数法定义hash函数+线性探测法解决hash冲突】数据结构实验之查找七:线性之哈希表
- 线性探测法构造哈希表(hash)
- 【哈希表】线性探测再散列的相关知识与计算
- 哈希表的C++实现(线性探测)
- C++ 哈希表 线性探测 二次探测 哈希桶
- 哈希表-开放地址法之线性探测代码(JAVA)
- (第13讲)哈希表的开放地址法中的线性探测