递归
迷宫问题
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)
}