使用hash原理,模拟数据库保存数据,直接操作内存编辑数据,
package main
import (
"errors"
"fmt"
"os"
)
//hash链表的基本使用
//思路
//1、创建一个hash结构体,里面保存自己自定义数量的链表数组
//2、创建一个链表,用来保存用户数据
//3、每次插入前先计算插入的哪一个数组,根据id从小到大依次插入,这样做是为了查询快
//定义方法
type HashFunc interface {
Push(link *Link) error
Find(id int) (*Link, error)
Del(id int) error
Update(id int) error
Each()
}
//用户数据链表
type Link struct {
Id int
Name string
Next *Link
}
//hashTable
type HashTable struct {
Table *[7]*Link
}
func (this *Link) publish(link *Link) (*Link, error) {
//当这张表为空时
if this == nil {
this = link
return this, nil
}
//插入的元素小于第一个元素时
tmp := this
if this.Id > link.Id {
link.Next = tmp
this = link
} else {
for {
if tmp.Next == nil {
break
}
if tmp.Next.Id < link.Id {
tmp = tmp.Next
} else {
break
}
}
link.Next = tmp.Next
tmp.Next = link
}
return this, nil
}
//获取插入表id
func getHashIndex(id int) int {
return id % 7
}
//添加元素方法
func (this *HashTable) Push(link *Link) error {
//把hashTable的7个数组看成7张表,当我们插入元素时根据自己的规则获取需要插入到哪张表,这样设计的目的是提高我们操作数据的数度,理论上有多少张表就可以提高多少倍的熟读;
//获取需要插入到那张表
index := getHashIndex(link.Id)
k, err := this.Table[index].publish(link)
if err != nil {
return err
}
this.Table[index] = k
return nil
}
//查询方法
func (this *HashTable) Find(id int) (*Link, error) {
//获取表索引
index := getHashIndex(id)
//判断表是否为空
if this.Table[index] == nil {
return nil,errors.New("数据不存在")
}
tmp := this.Table[index]
for {
if tmp.Id == id {
return tmp,nil
}else {
if tmp.Next != nil{
tmp = tmp.Next
}else {
return nil,errors.New("数据不存在")
}
}
}
}
//删除方法
func (this *HashTable) Del(id int) error {
//获取表索引
index := getHashIndex(id)
//判断hash是否存在
tmp := this.Table[index]
if tmp == nil {
return errors.New("链表为空")
}
//判断第一个元素是否等于需要删除的元素
if tmp.Id == id {
this.Table[index] = tmp.Next
return nil
}
//第一个元素不等于需要删除的元素,所以从第二个开始查找
for {
if tmp.Next == nil {
return errors.New("id is not find")
}
if tmp.Next.Id == id {
tmp.Next = tmp.Next.Next
}else {
tmp = tmp.Next
}
}
}
//修改方法
func (this *HashTable) Update(id int,name string) error {
//获取表索引
index := getHashIndex(id)
//判断hash是否存在
tmp := this.Table[index]
if tmp == nil {
return errors.New("链表为空")
}
for {
if tmp.Id == id {
tmp.Name = name;
return nil
}
if tmp.Next != nil{
tmp = tmp.Next
}else {
break
}
}
return errors.New("id is not find")
}
//查看所有元素
func (this *HashTable) Each() {
table := this.Table
for key, val := range table {
if val == nil {
fmt.Printf("表%v为空\n",key)
continue
}
for {
fmt.Println(val)
if val.Next == nil {
break
}else {
val = val.Next
}
}
fmt.Println("------------------------------------")
}
}
func main() {
hashTale := new(HashTable)
table := [7]*Link{}
hashTale.Table = &table
link := &Link{}
fmt.Println("程序已启动。。。")
var flag int
for{
fmt.Println("|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|")
fmt.Println("1 查看列表")
fmt.Println("2 查找成员")
fmt.Println("3 修改成员")
fmt.Println("4 删除成员")
fmt.Println("5 添加成员")
fmt.Println("0 退出系统")
fmt.Print("请输入指令:")
_, err := fmt.Scan(&flag)
if err != nil {
fmt.Print("指令输入错误,请重新输入")
continue
}
switch flag {
case 1:
hashTale.Each()
case 2:
fmt.Print("成员ID:")
_, err := fmt.Scan(&link.Id)
if err != nil {
fmt.Print("指令输入错误,请重新输入")
continue
}
res, err := hashTale.Find(link.Id)
if err != nil {
fmt.Println(err)
}else {
fmt.Println(res)
}
case 3:
fmt.Print("成员ID:")
_, err := fmt.Scan(&link.Id)
if err != nil {
fmt.Print("指令输入错误,请重新输入")
continue
}
fmt.Print("成员name:")
_, err = fmt.Scan(&link.Name)
if err != nil {
fmt.Print("指令输入错误,请重新输入")
continue
}
if err := hashTale.Update(link.Id,link.Name);err != nil{
fmt.Println(err)
}
case 4:
fmt.Print("成员ID:")
_, err := fmt.Scan(&link.Id)
if err != nil {
fmt.Print("指令输入错误,请重新输入")
continue
}
if err := hashTale.Del(link.Id);err != nil {
fmt.Println(err)
}
case 5:
fmt.Print("成员ID:")
_, err := fmt.Scan(&link.Id)
if err != nil {
fmt.Print("指令输入错误,请重新输入")
continue
}
fmt.Print("成员name:")
_, err = fmt.Scan(&link.Name)
if err != nil {
fmt.Print("指令输入错误,请重新输入")
continue
}
if err := hashTale.Push(link);err != nil{
fmt.Println(err)
}else {
fmt.Println("添加成功")
}
case 0:
os.Exit(0)
}
fmt.Println()
}
}