數據結構第18節 散列表 - 應用

散列表(Hash Table),也被稱為哈希表,是一種數據結構,它通過使用哈希函數將鍵映射到數組的某個位置來實現快速查找。散列表通常提供平均時間復雜度為O(1)的查找、插入和刪除操作,這使得它們在處理大量數據時非常高效。

基本概念

  • 哈希函數:一個將鍵轉換為數組索引的函數。理想情況下,這個函數應該均勻地分布鍵,以避免沖突。
  • 沖突:當兩個或多個不同的鍵被哈希函數映射到同一個數組索引時,就發生了沖突。解決沖突的方法包括開放尋址法和鏈地址法。
  • 負載因子:是散列表中元素的數量與散列表大小的比例。當負載因子過高時,散列表可能需要重新調整大小(擴容)以減少沖突。

Java中的散列表實現

在Java中,散列表可以通過HashMap類實現,它是Java集合框架的一部分。HashMap允許我們存儲鍵值對,并且提供了快速的查找、插入和刪除操作。

示例代碼

假設我們要創建一個簡單的散列表,用于存儲學生ID和他們的成績。以下是一個使用HashMap的示例:

import java.util.HashMap;public class StudentScores {public static void main(String[] args) {HashMap<Integer, Integer> scores = new HashMap<>();// 插入數據scores.put(101, 90);scores.put(102, 85);scores.put(103, 95);// 查找數據System.out.println("Score of student 101: " + scores.get(101));// 更新數據scores.put(101, 92);System.out.println("Updated score of student 101: " + scores.get(101));// 刪除數據scores.remove(102);System.out.println("After removing student 102: " + scores);// 檢查是否包含鍵System.out.println("Does the map contain student 101? " + scores.containsKey(101));}
}

在這個例子中,HashMap<Integer, Integer>表示散列表的鍵類型是整數,值類型也是整數。我們使用put方法插入數據,get方法查找數據,remove方法刪除數據,以及containsKey方法檢查散列表是否包含特定的鍵。

散列表的內部工作原理

HashMap的內部使用一個數組來存儲鍵值對,每個位置上可以是一個鏈表或者紅黑樹(當鏈表長度達到一定閾值時)。當向HashMap中添加元素時,它會計算鍵的哈希碼,然后使用該哈希碼確定元素在數組中的位置。如果發生沖突,即多個鍵的哈希碼指向同一位置,那么這些鍵值對會被鏈接在一起形成一個鏈表或紅黑樹。

當從HashMap中查找元素時,同樣的哈希計算過程被用來定位元素。如果存在沖突,則遍歷鏈表或紅黑樹直到找到正確的元素。

總結

散列表通過哈希函數和解決沖突的策略來實現高效的鍵值存儲和檢索。在Java中,HashMap是實現這一功能的常用工具。理解其內部工作原理有助于更有效地使用它并優化應用程序的性能。

讓我們通過另一個案例來深入理解散列表(哈希表)的應用。這次我們將創建一個簡單的圖書管理系統,使用散列表來存儲和管理圖書館中的書籍信息。

案例:圖書管理系統

在這個案例中,我們將使用HashMap來存儲圖書的ISBN(國際標準書號)作為鍵,以及每本書的詳細信息作為值。圖書的詳細信息可以用一個自定義的Book類來表示,其中包含書名、作者和出版年份等屬性。

創建Book

首先,我們需要創建一個Book類,用于存儲圖書的詳細信息。

public class Book {private String title;private String author;private int publicationYear;public Book(String title, String author, int publicationYear) {this.title = title;this.author = author;this.publicationYear = publicationYear;}@Overridepublic String toString() {return "Book{" +"title='" + title + '\'' +", author='" + author + '\'' +", publicationYear=" + publicationYear +'}';}
}
使用HashMap創建圖書管理系統

接下來,我們使用HashMap<String, Book>來創建圖書管理系統。我們將ISBN作為鍵,因為它是圖書的唯一標識符。

import java.util.HashMap;public class LibrarySystem {private HashMap<String, Book> books;public LibrarySystem() {this.books = new HashMap<>();}public void addBook(String isbn, String title, String author, int publicationYear) {Book book = new Book(title, author, publicationYear);books.put(isbn, book);}public Book getBook(String isbn) {return books.get(isbn);}public void removeBook(String isbn) {books.remove(isbn);}public boolean containsBook(String isbn) {return books.containsKey(isbn);}
}
測試圖書管理系統

現在我們可以創建一個LibrarySystem實例,并測試添加、獲取和刪除圖書的功能。

public class Main {public static void main(String[] args) {LibrarySystem library = new LibrarySystem();// 添加圖書library.addBook("978-0-306-40615-7", "The C Programming Language", "Brian W. Kernighan", 1978);library.addBook("978-0-201-63361-0", "Clean Code: A Handbook of Agile Software Craftsmanship", "Robert C. Martin", 2008);// 獲取圖書信息Book book = library.getBook("978-0-306-40615-7");System.out.println(book); // 輸出: Book{title='The C Programming Language', author='Brian W. Kernighan', publicationYear=1978}// 檢查圖書是否存在System.out.println(library.containsBook("978-0-201-63361-0")); // 輸出: true// 刪除圖書library.removeBook("978-0-201-63361-0");System.out.println(library.containsBook("978-0-201-63361-0")); // 輸出: false}
}

在這個案例中,我們利用散列表的快速查找特性來高效地管理圖書館中的圖書信息。由于ISBN是唯一的,因此使用它作為散列表的鍵可以確保沒有重復的條目,同時也簡化了查找和刪除操作。

通過這個案例,你可以看到散列表在實際應用中如何提高數據訪問效率,尤其是在處理具有唯一標識符的大數據集時。

好的,讓我們繼續擴展案例,這次我們將構建一個更復雜的場景——一個任務管理器,它能夠幫助用戶跟蹤個人的任務清單。我們將使用散列表來存儲任務,以便于快速查找和管理。

案例:任務管理器

定義Task

首先,我們需要定義一個Task類來存儲任務的信息,比如任務的名稱、描述、優先級和截止日期。

import java.time.LocalDate;public class Task {private String name;private String description;private int priority;private LocalDate dueDate;public Task(String name, String description, int priority, LocalDate dueDate) {this.name = name;this.description = description;this.priority = priority;this.dueDate = dueDate;}public String getName() {return name;}public String getDescription() {return description;}public int getPriority() {return priority;}public LocalDate getDueDate() {return dueDate;}@Overridepublic String toString() {return "Task{" +"name='" + name + '\'' +", description='" + description + '\'' +", priority=" + priority +", dueDate=" + dueDate +'}';}
}
創建任務管理器

接下來,我們創建一個TaskManager類,使用HashMap來存儲任務。我們將使用任務的名稱作為鍵,因為任務的名稱應該是唯一的,以避免混淆。

import java.util.HashMap;public class TaskManager {private HashMap<String, Task> tasks;public TaskManager() {this.tasks = new HashMap<>();}public void addTask(Task task) {tasks.put(task.getName(), task);}public Task getTask(String name) {return tasks.get(name);}public void removeTask(String name) {tasks.remove(name);}public boolean containsTask(String name) {return tasks.containsKey(name);}
}
測試任務管理器

現在,我們可以創建一個TaskManager實例,并測試添加、獲取和刪除任務的功能。

import java.time.LocalDate;public class Main {public static void main(String[] args) {TaskManager manager = new TaskManager();// 添加任務manager.addTask(new Task("Buy groceries", "Milk, bread, eggs", 2, LocalDate.of(2024, 7, 12)));manager.addTask(new Task("Write report", "Finish Q2 sales report", 1, LocalDate.of(2024, 7, 15)));// 獲取任務Task task = manager.getTask("Write report");System.out.println(task); // 輸出: Task{name='Write report', description='Finish Q2 sales report', priority=1, dueDate=2024-07-15}// 檢查任務是否存在System.out.println(manager.containsTask("Buy groceries")); // 輸出: true// 刪除任務manager.removeTask("Buy groceries");System.out.println(manager.containsTask("Buy groceries")); // 輸出: false}
}

擴展功能:按優先級排序

為了使任務管理器更加實用,我們可以添加一個功能來按優先級對任務進行排序。雖然HashMap不保證順序,但我們可以在TaskManager類中添加一個方法,使用優先級對任務進行排序并返回一個新的List

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;public class TaskManager {// ...public List<Task> getTasksSortedByPriority() {List<Task> sortedTasks = new ArrayList<>(tasks.values());Collections.sort(sortedTasks, Comparator.comparingInt(Task::getPriority));return sortedTasks;}
}

然后,在Main類中,我們可以調用getTasksSortedByPriority方法來獲取按優先級排序的任務列表。

// 在Main類中
List<Task> sortedTasks = manager.getTasksSortedByPriority();
sortedTasks.forEach(System.out::println);

通過這些擴展,我們不僅能夠有效地存儲和管理任務,還能根據優先級對它們進行排序,從而幫助用戶更好地組織和規劃他們的工作。這個案例展示了散列表如何與其他數據結構如列表結合使用,以滿足更復雜的需求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/45159.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/45159.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/45159.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【mybatis】mybatisX插件概述

一、主要功能 智能補全與提示 MyBatisX 可以智能地提示和補全 SQL 語句中的關鍵字、表名、列名等信息&#xff0c;從而顯著提高開發效率。代碼生成器 雖然 MyBatisX 本身可能不直接提供一個完整的、獨立的代碼生成器&#xff0c;但它可能集成了或支持與其他代碼生成工具&#…

鹵味江湖中,周黑鴨究竟該抓住什么賽點?

近年來&#xff0c;鹵味江湖的決斗從未停止。 隨著休閑鹵味、佐餐鹵味等細分賽道逐漸形成&#xff0c;“鹵味三巨頭”&#xff08;周黑鴨、絕味食品、煌上煌&#xff09;的牌桌上有了更多新對手&#xff0c;賽道變擠了&#xff0c;“周黑鴨們”也到了轉型關鍵期。 這個夏天&a…

MySQL字符串相關數據處理函數

目錄 1. 轉大小寫 2. 截取字符串 sunstr 3. 獲取字符長度 4. 字符串拼接 concat 5. 去掉空白 trim 1. 轉大小寫 轉大寫&#xff1a;upper() 轉小寫&#xff1a;lower() 雖然MySQL不嚴格區分大小寫&#xff0c;但是我們還是需要掌握這種大小寫的操作以方便學習其他…

python的入門知識(下)

目錄 學習內容數字字符串、列表和元組映射和集合類型 學習內容 數字 長整型&#xff08;Long Integer&#xff09;: 在Python中&#xff0c;整數沒有大小限制&#xff0c;但是可以用大寫或小寫的L來表示長整型&#xff0c;盡管這不是Python 3推薦的做法。 復數&#xff08;Co…

Nessus相關

tenable 1 安裝nessus scanner 1 )安裝nessus scanner: 方法一 curl -H X-Key: xxxxx https://cloud.tenable.com/install/scanner?namescanner-name&groupsscanner-group | bash方法二&#xff1a; **# for ubuntu, its https://www.tenable.com/downloads/api/v1/pu…

【JavaScript腳本宇宙】JavaScript 庫概覽:數字、貨幣值、日期時間處理一網打盡

簡化數據處理&#xff1a;掌握六大 JavaScript 庫的核心功能和使用技巧 前言 在現代的軟件開發中&#xff0c;處理數字、貨幣和日期時間是非常常見的需求。為了簡化這些任務&#xff0c;開發人員可以使用各種 JavaScript 庫來輕松地進行數字格式化、貨幣計算和日期時間操作。…

Google登錄時人機身份驗證的圖片類型和通過的經驗建議,以及一些常見問題

很多朋友在登錄谷歌賬號時&#xff0c;都遇到過要求人機身份驗證的步驟&#xff0c;而且有一些時候人機身份驗證這個步驟很讓人糾結&#xff0c;甚至壓根就出不來具體的驗證圖片&#xff0c;或者花了十幾分鐘、幾十分鐘都過不去。 所以今天GG賬號服務就來為您解析一下谷歌登錄…

初學SpringMVC之接收請求參數及數據回顯

pom.xml 文件導入 lombok 的依賴 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version></dependency> Controller 表示這是一個控制器 RequestParam 表示從前端接收…

夏日智啟:我的Datawhale AI夏令營探索之旅

前言 最近幾年&#xff0c;AI&#xff08;人工智能&#xff09;的發展呈現出了前所未有的迅猛勢頭&#xff0c;其影響力和應用范圍不斷擴大&#xff0c;深刻地改變著我們的生活、工作和社會結構。尤其是AI大模型技術&#xff0c;國內外可謂是“百模大戰”&#xff0c;百舸爭流…

github恢復碼怎么備份

https://docs.github.com/zh/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication-recovery-methods

最強文本編輯器 VIM 指令大全

Vim 是從 Vi 編輯器發展出來的一款極其強大的文本編輯器&#xff0c;它保留了 Vi 編輯器的所有功能&#xff0c;并添加了許多新特性。Vim 具有代碼補全、語法高亮、錯誤跳轉、批量化處理等編輯功能&#xff0c;還支持異常豐富的插件擴展&#xff0c;且整個編輯全程可通過鍵盤完…

谷歌插件之一鍵關閉同域名頁面

歡迎來到我的博客&#xff0c;代碼的世界里&#xff0c;每一行都是一個故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交給時間 &#x1f3e0; &#xff1a;小破站 谷歌插件之一鍵關閉同域名頁面 前言項目結構mainfest.jsonbackgroud.js 項目實現效果展示展望 前…

13019.CUDA問題積累

文章目錄 1 內存不斷增長的問題1.1 主機從GPU拷貝內存1.1.1 htop 內存增長到一定階段后&#xff0c;保持穩定 1.2 GPU拷貝到Host修改之后內存穩定無變化1.3 結論 2 主機與GPU數據拷貝方案2.1 cudaMemcpy 拷貝內存2.2 cudaMemcpyAsync 異步數據拷貝2.3 采用多線程拷貝技術2.3.1 …

群主必學!輕松Get如何解散微信群的技巧

作為一個微信群的群主&#xff0c;解散群聊可能是你需要掌握的重要技能之一。不管是因為群聊的目的已經達成&#xff0c;還是因為群成員過少或不活躍&#xff0c;了解如何解散微信群都能幫助你更好地管理你的群聊。 如何解散微信群&#xff1f;本文將為您提供一些簡單易行的技…

代碼隨想錄算法訓練營第五十天| 739. 每日溫度、496.下一個更大元素 I、503.下一個更大元素II

739. 每日溫度 題目鏈接&#xff1a; 739. 每日溫度 文檔講解&#xff1a;代碼隨想錄 狀態&#xff1a;不會 思路&#xff1a; 這道題需要找到下一個更大元素。 使用棧來存儲未找到更高溫度的下標&#xff0c;那么棧中的下標對應的溫度從棧底到棧頂是遞減的。這意味著&#xff…

Redis數據同步

文章簡單介紹基于redis-shake的redis數據同步&#xff0c;該工具基于每個節點同步數據&#xff0c;即每個主節點需同步一次&#xff0c;才能完成整個redis集群的數據同步。 1、redis節點操作 ### 查看redis版本 ./bin/redis-server --version### 登錄redis ./bin/redis-cli -…

改變Ubuntu的Tab沒有縮進4格(Makefile)

1.vim里的Tab 用vi指令打開這個文件&#xff0c;沒有的話就新創建一個 vi ~/.vimrc在打開的文件中輸入以下兩行 1 set tabstop42 set shiftwidth4 ~ Esc &#xff1a; x&#xff0c;保存并退出即可 資料來源&#xff1a; 2024年5月21日-vi/vim …

Linux Ubuntu MySQL環境安裝

1. 更新軟件源 首先&#xff0c;確保你的Ubuntu系統已經更新了軟件源列表&#xff0c;以便能夠下載到最新的軟件包。打開終端并輸入以下命令&#xff1a; sudo apt update 2. 安裝MySQL服務器 打開終端并輸入以下命令來安裝MySQL服務器 sudo apt install mysql-server 在…

一個便捷的web截圖庫~【送源碼】

隨著時間的發展&#xff0c;前端開發的范圍越來越廣&#xff0c;能夠實現的功能也越來越多&#xff0c;要實現的功能也五花八門&#xff0c;今天就給大家介紹一個web截圖庫,讓前端也能實現截圖功能—— js-web-screen-shot js-web-screen-shot js-web-screen-shot 是一個基于 …

嵌入式板級支持包(BSP)80道面試題及參考答案(3萬字長文)

目錄 解釋什么是通用輸入輸出(GPIO)接口及其在BSP中的作用。 描述SPI接口的主要特點和用途。 說明IC總線協議的工作原理。 如何在BSP中配置一個UART接口? USB設備控制器在BSP中的初始化步驟是什么? 以太網接口如何在BSP中被支持? 什么是SDIO,它在哪些場景下會被使…