1. 程式人生 > 其它 >資料結構-雜湊表

資料結構-雜湊表

一、雜湊表介紹

二、雜湊表引入與圖解

1.需求

2.圖解

三、雜湊表程式碼實現(Java)

import java.util.Scanner;


public class HashTabDemo {
    public static void main(String[] args) {

        //建立雜湊表
        HashTab hashTab = new HashTab(7);

        //寫一個簡單的選單
        String key = "";
        Scanner scanner = new Scanner(System.in);
        
while(true){ System.out.println("add:新增僱員"); System.out.println("list:顯示僱員"); System.out.println("find:查詢僱員"); System.out.println("delete:刪除僱員"); System.out.println("exit:退出系統"); key = scanner.next(); switch (key) {
case "add": System.out.println("輸入id"); int id = scanner.nextInt(); System.out.println("輸入名字"); String name = scanner.next(); //建立僱員 Emp emp = new Emp(id, name); hashTab.add(emp);
break; case "list": hashTab.list(); break; case "find": System.out.println("請輸入要查詢的僱員id"); id = scanner.nextInt(); hashTab.findEmpById(id); break; case "delete": System.out.println("請輸入要刪除的僱員id"); id = scanner.nextInt(); hashTab.deleteEmpById(id); break; case "exit": scanner.close(); System.exit(0); default: break; } } } } //建立HashTab 管理多條連結串列 class HashTab { private EmpLinkedList[] empLinkedListArray; private int size; //表示有多少條連結串列 public HashTab(int size){ this.size = size; //初始化empLinkedListArray empLinkedListArray = new EmpLinkedList[size]; //這時不要分別初始化每個連結串列 for (int i = 0; i < size; i++) { empLinkedListArray[i] = new EmpLinkedList(); } } //新增僱員 public void add(Emp emp){ //根據員工的id,得到該員工應當新增到哪條連結串列 int empLinkedListNo = hashFun(emp.id); //將emp 新增到對應的連結串列中 empLinkedListArray[empLinkedListNo].add(emp); } //遍歷所有的連結串列,遍歷hashtab public void list(){ for (int i = 0; i < size; i++) { empLinkedListArray[i].list(i); } } //根據輸入的id,查詢僱員 public void findEmpById(int id){ //使用雜湊函式確定到哪條連結串列查詢 int empLinkedListNo = hashFun(id); Emp emp = empLinkedListArray[empLinkedListNo].findEmpById(id); if(emp != null){//找到 System.out.printf("在第%d條連結串列中找到 僱員 id = %d\n", (empLinkedListNo+1), id); }else{ System.out.println("在雜湊表中,沒有找到該僱員~"); } } //根據輸入的id,刪除僱員 public void deleteEmpById(int id){ //使用雜湊函式確定到哪條連結串列查詢 int empLinkedListNo = hashFun(id); empLinkedListArray[empLinkedListNo].deleteEmpById(id); } //編寫雜湊函式,使用一個簡單取模法 public int hashFun(int id){ return id % size; } } //表示一個僱員 class Emp { public int id; public String name; public Emp next;//next 預設為 null public Emp(final int id, final String name) { this.id = id; this.name = name; } } //建立EmpLinkedList,表示連結串列 class EmpLinkedList { //頭指標,指向第一個Emp private Emp head = new Emp(-1,""); //預設null //新增僱員到連結串列 //說明 //1.假定,當新增僱員時,id是自增長,即id的分配總是從小到大 // 因此我們將該僱員直接加入到本連結串列的最後即可 public void add(Emp emp) { //如果是新增第一個僱員 if(head == null){ head = emp; return; } //如果不是第一個僱員,則使用一個輔助的指標,幫助定位到最後 Emp curEmp = head; while(true){ if(curEmp.next == null){//說明到連結串列最後 break; } curEmp = curEmp.next;//後移 } //退出時直接將emp 加入連結串列 curEmp.next = emp; } //遍歷連結串列的僱員資訊 public void list(int no){ if(head == null){ //說明連結串列為空 System.out.println("第"+(no+1)+" 條連結串列為空"); return; } System.out.println("第"+(no+1)+" 條連結串列為"); Emp curEmp = head; //輔助指標 while(true){ System.out.printf(" => id=%d name=%s\t", curEmp.id, curEmp.name); if(curEmp.next == null){//說明curEmp已經是最後節點 break; } curEmp = curEmp.next;//後移,遍歷 } System.out.println(); } //根據id查詢僱員 //如果查詢到,就返回Emp,如果沒有找到,就返回null public Emp findEmpById(int id){ if(head == null){ //說明連結串列為空 System.out.println("連結串列為空"); return null; } Emp curEmp = head;//輔助指標 while(true){ if(curEmp.id == id){//找到 break;//這時curEmp就指向要查詢的僱員 } //退出 if(curEmp.next == null){//說明遍歷當前連結串列沒有找到該僱員 curEmp = null; break; } curEmp = curEmp.next; } return curEmp; } //根據id刪除僱員 //如果查詢到,就刪除Emp,如果沒有找到,就返回null public void deleteEmpById(int id){ Emp temp = head; boolean flag = false;//標誌是否找到待刪除節點 while(true){ if(temp.next == null){ break; } if(temp.next.id == id){ //找到的待刪除節點的前一個節點temp flag = true; break; } temp = temp.next;//temp後移,遍歷 } //判斷flag if(flag){ //找到 //可以刪除 temp.next = temp.next.next; } else { System.out.printf("要刪除的%d 節點不存在\n", id); } } }