开发者学堂课程【Go 语言核心编程 - 数据结构和算法:数据结构和算法-哈希表(散列)4】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/627/detail/9868
数据结构和算法-哈希表(散列)4
一、基于 hashtable 的雇员关系系统的思路分析
1. 完成工人查找雇员
package main
Import (
“
fmt
”
“
os
”
)
//定义 emp
type Emp struct {
Id int
Name string
Next * Emp
}
//方法待定..
func (this * Emp) ShowMe () {
fmt .Printf(
“
链表%d 找到该雇员 %d,this.Id % 7,this.Id)
//定义 EmpLink
//我们这里的 EmpLink 不带表头,即第一个节点就存放雇员
type EmpLink struct {
Head * Emp
}
//方法待定..
//1.添加员工的方法,保证添加时,编号从小到大
func (this *EmpLink) Insert(emp *Emp) {
cur := thie.Head
// 这是辅助指针
var pre *Emp = nil
//这是一个辅助指针 pre 在 cur 前面
// 如果当前的 EmpLink 就是一个空链表
If cur == nil {
this.Head = emp
//完成
return
}
// 如果不是一个空链表,给 emp 找到对应的位置并插入
//思路是让 cur 和 emp 比较,然后让 pre 保持在 cur 前面
for {
If cur !=nil {
//比较
if cur.Id > emp.Id {
//找到位置
break
}
Pre = cur
//保证同步
cur = cur.Next
}else {
Break
}
}
//退出时,我们看下是否将 emp 添加到链表最后
pre.Next = emp
emp.Next = cur
}
//显示链表信息
func (this *EmpLink) ShowLink(no int) {
if this. Head == nil {
fmt.Printf(
“
链表%d 为空\n
”
,no)
return
}
//变量当前的链表,并显示数据
cur := this.Head
// 辅助的指针
for {
If cur != nil {
fmt.Printf(
“
链表%d 雇员id=%d 名字=%s ->
”
,no,cur.Id,cur.Name)
cur =cur.Next
} else {
Break
}
Fmt.PrintIn()
//换行处理
}
//根据 id 查找对应的雇员,如果没有就返回 nil ,用遍历方式就可以找到了,将当前链表头指针,不等于nil 就能一直寻找,假定id 是唯一的,找到之后直接返回就行,如果一直没有,就往下就行寻找,如果 整个for 循环都没有一个返回值,说明肯定找不到了,直接 return nil 。
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
}
//给 HashTable 编写 Insert 雇员的方法.
func (this *HashTable) Insert (emp *Emp) {
//使用散列函数,确定将该雇员添加到哪个链表,如果这个链表找不到就不用再找了,就说明肯定没有。
linkNo := this.HashFun(emp.Id)
//使用对应的链表添加
this.LinkArr[linkNo].Insert(emp) //
}
//编写方法,显示 hashtable 的所有雇员
func (this *HashTable) ShowALL() {
for
//编写一个散列方法
func (this *HashTable) HashFun(id int) int {
Return id % 7
//得到一个值,就是对于的链表的下标
}
//编写一个方法,完成查找
func (this *HashTable) FindById(id int) *Emp {
//使用散列函数,确定将该雇员应该在那个链表
linkNo :=this.HashFun(id)
Return this.LinkArr[linkNo].FindById(id)
}
func main() {
key :=
””
Id := 0
name :=
””
var hashtable HashTable
for {
fmt.PrintIn(
“
===============雇员系统菜单===============”)
fmt.PrintIn(“input 表示添加雇员”)
fmt.PrintIn(“show 表示显示雇员”)
fmt.PrintIn(“find 表示查找雇员”)
fmt.PrintIn(“exit 表示退出系统”)
fmt.PrintIn(“请输入你的选择”)
fmt.ScanIn(&key)
switch key {
case
“
input
”
:
fmt.PrintIn(
“
输入雇员 id
”
)
fmt.ScanIn(&id)
fmt.PrintIn(
“
输入雇员 name
”
)
fmt.ScanIn(&name)
emp := &Emp{
Id : id,
Name : name,
}
Hashtable.Insert(emp)
case
“
show
”
:
Hashtable.ShowAll()
case
“
find
”
:
fmt.PrintIn(
“
请输入id 号:
”
)
fmt.ScanIn(&id)
emp := hashtable.FindById(id)
if emp == nil {
fmt.Printf(
“
id=%d 的雇员不存在\n
”
,id)
//因为他本身就是一个雇员
} else {
//编写一个方法,显示雇员信息,显示自己的时候干脆把信息写一下,先把链表编号想出来,看看以前是怎么输出是使其保持一致,发现找到该雇员的 id,然后输出。
emp.ShowMe()
}
case
“
exit
”
:
os.Exit(0)
default:
fmt.PrintIn(
“
输入错误”)
}
}
}