Golang哈希表和二叉树的运用

递归

迷宫问题

package main

import "fmt"

//编写一个函数,完成老鼠找路
//myMap *[8][7]int:地图,保证是同一个地图,使用引用
//i,j表示对地图的哪个点进行测试
func SetWay(myMap *[8][7]int, i int, j int) bool {
   //分析出什么情况下,就找到出路
   //myMap[6][5] ==2
   if myMap[6][5] == 2 {
      return true
   } else {
      if myMap[i][j] == 0 { //这个点可以探测
         //假设这个点可以通,但是需要探测
         myMap[i][j] = 2

         if SetWay(myMap, i+1, j) { //下
            return true
         } else if SetWay(myMap, i, j+1) { //右
            return true
         } else if SetWay(myMap, i-1, j) { //上
            return true
         } else if SetWay(myMap, i, j-1) { //左
            return true
         } else { //死路
            myMap[i][j] = 3
            return false
         }

      } else {
         return false
      }
   }
}

func main() {
   //先创建一个二维数组,模拟
   //规则:
   //1.如果元素的值为1,就是墙
   //2.如果元素的值为0,是没有走过的点
   //3.如果元素的值为2,是一个通路
   //4.如果元素的值为3,是走过的点,但是走不通
   var myMap [8][7]int

   //先把地图的最上和最下设置为1
   for i := 0; i < 7; i++ {
      myMap[0][i] = 1
      myMap[7][i] = 1
      myMap[i][0] = 1
      myMap[i][6] = 1
   }
   myMap[3][1] = 1
   myMap[3][2] = 1
   for i := 0; i < 8; i++ {
      for j := 0; j < 7; j++ {
         fmt.Print(myMap[i][j], " ")
      }
      fmt.Println()
   }
   fmt.Println()
   SetWay(&myMap, 1, 1)
   for i := 0; i < 8; i++ {
      for j := 0; j < 7; j++ {
         fmt.Print(myMap[i][j], " ")
      }
      fmt.Println()
   }
}

哈希表(散列)

哈希表的基本介绍

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

哈希表实现案例

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 := this.Head   //辅助指针
   var pre *Emp = nil //辅助指针
   //如果当前的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
      }
   }
   //退出时,我们将

   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\n", no, cur.Id, cur.Name)
         cur = cur.Next
      } else {
         break
      }
   }
   fmt.Println()
}

//根据id查找对应的雇员
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,含有一个链表数组
type HashTable struct {
   LinkArr [7]EmpLink
}

//给HashTable 编写Insert 雇员的方法
func (this *HashTable) Insert(emp *Emp) {
   //使用散列函数,确定将该雇员添加到哪个链表
   linkNo := this.HashFun(emp.Id)
   //使用对应的链表添加
   this.LinkArr[linkNo].Insert(emp)
}

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

//编写一个散列方法
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.Println("=============雇员系统菜单==============")
      fmt.Println("input 表示添加雇员")
      fmt.Println("show 表示显示雇员")
      fmt.Println("find 表示查找雇员")
      fmt.Println("exit 表示退出雇员")
      fmt.Println("请输入你的选择")
      fmt.Scanln(&key)
      switch key {
      case "input":
         fmt.Println("输入雇员id")
         fmt.Scanln(&id)
         fmt.Println("输入雇员name")
         fmt.Scanln(&name)
         emp := &Emp{
            Id:   id,
            Name: name,
         }
         hashtable.Insert(emp)
      case "show":
         hashtable.ShowAll()
      case "find":
         fmt.Println("请输入id号")
         fmt.Scanln(&id)
         emp := hashtable.FindById(id)
         if emp == nil {
            fmt.Printf("id = %d 的雇员不存在\n", id)
         } else {
            //编写一个方法,显示雇员信息
            emp.ShowMe()
         }
      case "exit":
         os.Exit(0)
      default:
         fmt.Println("输入错误...")

      }
   }
}

二叉树

前序遍历,中序遍历,后续遍历

package main

import "fmt"

type Hero struct {
   No    int
   Name  string
   Left  *Hero
   Right *Hero
}

//前序遍历[先输root结点,然后再输出左子树,然后再输出右子树]Ⅰ
func PreOrder(node *Hero) {
   if node != nil {
      fmt.Printf("no=%d name=%s \n", node.No, node.Name)
      PreOrder(node.Left)
      PreOrder(node.Right)
   }
}

中序遍历[先输出root的左子树,再输root结点,最后输出root的右子树]
func InfixOrder(node *Hero) {
   if node != nil {
      PreOrder(node.Left)
      fmt.Printf("no=%d name=%s \n", node.No, node.Name)
      PreOrder(node.Right)
   }
}

//后续遍历
func PostOrder(node *Hero) {
   if node != nil {
      PreOrder(node.Left)
      PreOrder(node.Right)
      fmt.Printf("no=%d name=%s \n", node.No, node.Name)

   }
}

func main() {
   //构建一个二叉树
   root := &Hero{
      No:   1,
      Name: "JJ",
   }
   left1 := &Hero{
      No:   2,
      Name: "ll",
   }
   right1 := &Hero{
      No:   3,
      Name: "kk",
   }
   root.Left = left1
   root.Right = right1

   right2 := &Hero{
      No:   4,
      Name: "kkdd",
   }
   right1.Right = right2

   PreOrder(root)
   fmt.Println()
   InfixOrder(root)
   fmt.Println()
   PostOrder(root)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值