數據結構hash表

看一個實際需google公司的一個上機題:

有一個公司,當有新的員工來報道時,要求將該員工的信息加入(id,性別,年齡,住址..),當輸入該員工的id,要求查找到該員工的 所有信息.

要求: 不使用數據庫,儘量節省內存,速度越快越好=>哈希表(散列)

哈希表的基本介紹

散列表Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列

創建一個鏈表添加刪除遍歷

class EmpLinkedList {
    //頭指針,執行第一個Emp,因此我們這個鏈表的head 是直接指向第一個Emp
    private Emp head; //默認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.print("第 "+(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;// 後移判斷下一個id
        }

        return curEmp;
    }

}

編寫散列函數, 使用一個簡單取模法更具id分配到不同列表中

   public int hashFun(int id) {
        return id % size;
    }

 創建hashTable

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 int hashFun(int id) {
        return id % size;
    }


}

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章