数据结构与算法之散列表 开放寻址法实现 线性探测 / Java 示例

数据结构与算法阿木 发布于 5 天前 1 次阅读


摘要:

散列表(Hash Table)是一种基于散列函数将键映射到表中的位置的数据结构,它提供了快速的查找、插入和删除操作。开放寻址法是散列表的一种实现方式,其中当散列函数冲突时,通过探测其他位置来找到可用的槽位。本文将围绕线性探测法实现散列表,通过Java代码示例进行分析。

一、

散列表是一种非常高效的数据结构,它通过散列函数将键映射到表中的位置。当散列函数冲突时,开放寻址法通过探测其他位置来找到可用的槽位。线性探测是开放寻址法中的一种,它按照线性顺序探测下一个槽位。本文将详细介绍线性探测法实现散列表的原理和Java代码实现。

二、线性探测法原理

线性探测法的基本思想是,当散列函数冲突时,从冲突的位置开始,依次探测下一个槽位,直到找到一个空槽位为止。如果整个散列表都被填满,那么探测过程将回绕到散列表的开始位置。

线性探测法的优点是简单易实现,但是它存在一个称为“聚集”的问题。当散列表中的元素很多时,冲突的概率会增加,导致探测过程变长,从而降低散列表的性能。

三、Java代码实现

以下是一个使用线性探测法实现散列表的Java代码示例:

java

public class LinearProbingHashTable {


private int size;


private int capacity;


private String[] table;

public LinearProbingHashTable(int capacity) {


this.capacity = capacity;


this.table = new String[capacity];


this.size = 0;


}

private int hash(String key) {


return Math.abs(key.hashCode()) % capacity;


}

public void insert(String key) {


if (size == capacity) {


throw new IllegalStateException("Table is full");


}


int index = hash(key);


while (table[index] != null) {


index = (index + 1) % capacity;


}


table[index] = key;


size++;


}

public boolean contains(String key) {


int index = hash(key);


while (table[index] != null) {


if (table[index].equals(key)) {


return true;


}


index = (index + 1) % capacity;


}


return false;


}

public void delete(String key) {


int index = hash(key);


while (table[index] != null) {


if (table[index].equals(key)) {


table[index] = null;


size--;


return;


}


index = (index + 1) % capacity;


}


}

public void display() {


for (int i = 0; i < capacity; i++) {


if (table[i] != null) {


System.out.print(table[i] + " ");


}


}


System.out.println();


}


}

public class Main {


public static void main(String[] args) {


LinearProbingHashTable hashTable = new LinearProbingHashTable(10);


hashTable.insert("apple");


hashTable.insert("banana");


hashTable.insert("cherry");


hashTable.insert("date");


hashTable.insert("elderberry");

hashTable.display();

System.out.println("Contains 'banana': " + hashTable.contains("banana"));


System.out.println("Contains 'fig': " + hashTable.contains("fig"));

hashTable.delete("banana");


hashTable.display();


}


}


四、代码分析

1. `LinearProbingHashTable` 类定义了一个线性探测散列表,包含一个字符串数组 `table` 用于存储键值对,以及 `size` 和 `capacity` 分别表示散列表的大小和容量。

2. `hash` 方法使用 `hashCode` 方法计算键的散列值,并取模 `capacity` 以确保散列值在数组范围内。

3. `insert` 方法将键插入散列表。如果散列表已满,则抛出异常。使用 `hash` 方法计算散列值,然后通过线性探测找到空槽位。

4. `contains` 方法检查散列表中是否存在指定的键。使用 `hash` 方法计算散列值,然后通过线性探测查找键。

5. `delete` 方法从散列表中删除指定的键。使用 `hash` 方法计算散列值,然后通过线性探测找到键,并将其设置为 `null`。

6. `display` 方法打印散列表的内容。

五、总结

本文通过Java代码示例详细介绍了线性探测法实现散列表的原理和实现过程。线性探测法是一种简单易实现的开放寻址法,但需要注意聚集问题。在实际应用中,可以根据具体需求选择合适的散列函数和探测方法,以提高散列表的性能。