golang数据结构之散哈希表(Hash)

时间:2022-07-23
本文章向大家介绍golang数据结构之散哈希表(Hash),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

hash.go

package hash

import (
    "fmt"
)

type Emp struct {
    ID   int
    Name string
    Next *Emp
}

//第一个节点就存放员工
type EmpLink struct {
    Head *Emp
}

//定义HashTable
type HashTable struct {
    LinkArr [7]EmpLink
}

//添加员工的方法
func (empl *EmpLink) InsertEmp(emp *Emp) {
    cur := empl.Head
    var pre *Emp = nil
    if cur == nil {
        empl.Head = emp
        return
    }
    //如果不是一个空链表,找到对应的位置并插入
    for {
        if cur != nil {
            if cur.ID >= emp.ID {
                break
            }
            pre = cur
            cur = cur.Next
        } else {
            break
        }
    }
    pre.Next = emp
    emp.Next = cur
}
func (hash *HashTable) Insert(emp *Emp) {
    //使用散列函数,确定将员工添加到哪个链表
    linkNum := hash.HashFunc(emp.ID)
    hash.LinkArr[linkNum].InsertEmp(emp)
}

func (empl *EmpLink) FindByID(id int) *Emp {
    cur := empl.Head
    for {
        if cur != nil && cur.ID == id {
            return cur
        } else if cur == nil {
            break
        }
        cur = cur.Next
    }
    return nil
}

func (hash *HashTable) Find(id int) *Emp {
    //使用散列函数确定在哪个链表
    linkNum := hash.HashFunc(id)
    return hash.LinkArr[linkNum].FindByID(id)
}

//散列方法
func (hash *HashTable) HashFunc(id int) int {
    return id % 7
}
func (empl *EmpLink) ShowLink(num int) {
    if empl.Head == nil {
        fmt.Printf("当前%d链表为空n", num)
        return
    }
    //否则遍历显示数据
    cur := empl.Head
    for {
        if cur != nil {
            fmt.Printf("链表:%d,员工id:%d,员工名字:%s-->", num, cur.ID, cur.Name)
            cur = cur.Next
        } else {
            break
        }
    }
    fmt.Println(``)
}

func (hash *HashTable) Show() {
    for i := 0; i < len(hash.LinkArr); i++ {
        hash.LinkArr[i].ShowLink(i)
    }
}

func (emp *Emp) ShowMe() {
    fmt.Printf("链表%d找到该员工 %dn", emp.ID%7, emp.ID)
}

main.go

package main

import (
    "fmt"
    "go_code/data_structure/hash"
    "os"
)

func main() {

    key := ""
    id := 0
    name := ""
    var hashTable hash.HashTable
    for {
        fmt.Println("==========员工菜单==========")
        fmt.Println("insert 表示添加员工")
        fmt.Println("show   表示显示员工")
        fmt.Println("find   表示查询员工")
        fmt.Println("exit   表示退出员工")
        fmt.Println("请输入你的选择:")
        fmt.Scanln(&key)
        switch key {
        case "insert":
            fmt.Println("请输入员工id:")
            fmt.Scanln(&id)
            fmt.Println("请输入员工名字:")
            fmt.Scanln(&name)
            emp := &hash.Emp{
                ID:   id,
                Name: name,
            }
            hashTable.Insert(emp)
        case "show":
            hashTable.Show()
        case "find":
            fmt.Println("请输入你要查找的id:")
            fmt.Scanln(&id)
            emp := hashTable.Find(id)
            if emp == nil {
                fmt.Printf("id=%d的员工不存在n", id)
            } else {
                //显示雇员信息
                emp.ShowMe()

            }
        case "exit":
            os.Exit(0)
        }
    }
}

运行结果:

f:goprojectsrcgo_codedata_structure>go run main.go ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: insert 请输入员工id: 1 请输入员工名字: bob ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: insert 请输入员工id: 8 请输入员工名字: mike ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: insert 请输入员工id: 15 请输入员工名字: tom ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: insert 请输入员工id: 57 请输入员工名字: pop ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: show 当前0链表为空 链表:1,员工id:1,员工名字:bob-->链表:1,员工id:8,员工名字:mike-->链表:1,员工id:15,员工名字:tom-->链表:1,员工id:57,员工名字:pop--> 当前2链表为空 当前3链表为空 当前4链表为空 当前5链表为空 当前6链表为空 ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: insert 请输入员工id: 36 请输入员工名字: bib ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: show 当前0链表为空 链表:1,员工id:1,员工名字:bob-->链表:1,员工id:8,员工名字:mike-->链表:1,员工id:15,员工名字:tom-->链表:1,员工id:36,员工名字:bib-->链表:1,员工id:57,员工名字:pop--> 当前2链表为空 当前3链表为空 当前4链表为空 当前5链表为空 当前6链表为空 ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: insert 请输入员工id: 12 请输入员工名字: viv ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: show 当前0链表为空 链表:1,员工id:1,员工名字:bob-->链表:1,员工id:8,员工名字:mike-->链表:1,员工id:15,员工名字:tom-->链表:1,员工id:36,员工名字:bib-->链表:1,员工id:57,员工名字:pop--> 当前2链表为空 当前3链表为空 当前4链表为空 链表:5,员工id:12,员工名字:viv--> 当前6链表为空 ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: find 请输入你要查找的id: 12 链表5找到该员工 12 ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: find 请输入你要查找的id: 7 id=7的员工不存在 ==========员工菜单========== insert 表示添加员工 show 表示显示员工 find 表示查询员工 exit 表示退出员工 请输入你的选择: exit

f:goprojectsrcgo_codedata_structure>