数据结构之Hash表

旧巷老猫 提交于 2019-12-01 20:18:16

阅读目录

一、Hash表介绍

二、Hash表应用

一、Hash表介绍

二、Hash表应用

package main

import (
    "fmt"
    "os"
)

func main() {
    var hashtable HashTable
    key := ""
    id := 0
    name := ""
    for {
        fmt.Println("===========雇员系统菜单=============")
        fmt.Println("===========input 添加雇员=============")
        fmt.Println("===========show 显示雇员=============")
        fmt.Println("===========update 修改雇员=============")
        fmt.Println("===========find 查找雇员=============")
        fmt.Println("===========exit 退出=============")
        fmt.Println("请输入你的选择")
        fmt.Scanln(&key)
        switch key {
        case "input":
            fmt.Println("请输入雇员id")
            fmt.Scanln(&id)
            fmt.Println("请输入雇员名")
            fmt.Scanln(&name)
            emp := &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)
        default:
            fmt.Println("输入错误...")
        }
    }
}

// 链表Emp
type Emp struct {
    Id   int
    Name string
    Next *Emp
}

func (this *Emp) ShowMe() {
    fmt.Printf("链表%d,雇员%d,名称%s\n", this.Id%7+1, this.Id, this.Name)
}

//EmpLink -> 不带表头
type EmpLink struct {
    Head *Emp
}

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

// 显示当前列表的信息
func (this *EmpLink) Show(no int) {
    if this.Head == nil {
        fmt.Printf("当前链表【%d】数据为空\n", no+1)
        return
    }
    cur := this.Head
    for {
        if cur != nil {
            fmt.Printf("链表%d,雇员id=%d,名字=%s -->", no+1, cur.Id, cur.Name)
            cur = cur.Next
        } else {
            break
        }
    }
    fmt.Println()
}

//添加员工的方法
func (this *EmpLink) Insert(emp *Emp) {
    //添加时 编号从小到达
    cur := this.Head
    var pre *Emp = nil //pre在cur之前
    //如果当前Emplink空链表
    if cur == nil {
        this.Head = emp
        return
    }
    // 添加最开始
    if emp.Id < cur.Id {
        this.Head = emp
        this.Head.Next = cur
        return
    }
    //非空链表,给emp找到对应的位置并插入
    //思路 让cur与emp比较  且 pre保持在cur之前
    for {
        if cur != nil {
            if cur.Id >= emp.Id {
                break // 找到位置
            }
            pre = cur
            cur = cur.Next
        } else {
            // 最大值得时候
            break
        }
    }
    // 退出链表时
    //if cur == nil{
    pre.Next = emp
    emp.Next = cur
    //}

}

//含一个链表数组
type HashTable struct {
    LinkArr [7]EmpLink
}

// HashTable ->insert
func (this *HashTable) Insert(emp *Emp) {
    //使用散列函数确认添加到哪个链表数组
    linkNo := this.HashFunc(emp.Id)
    //使用对应的散链表数组添加
    this.LinkArr[linkNo].Insert(emp)
}

// HashTable ->show 显示所有雇员
func (this *HashTable) show() {
    for i := 0; i < len(this.LinkArr); i++ {
        this.LinkArr[i].Show(i)
    }

}

func (this *HashTable) Find(id int) *Emp {
    // 确认链表
    no := this.HashFunc(id)
    return this.LinkArr[no].FindById(id)
}

// 编写一个散列的方法
func (this *HashTable) HashFunc(id int) int {
    return id % 7 //对应链表的下标
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!