1. 数据结构的介绍
2. 数据结构和算法的关系
3. 稀疏数组
package main
import (
"fmt"
)
type ValNode struct {
row int
col int
val int
}
func main() {
//1. 先创建一个原始数组
var chessMap [11][11]int
chessMap[1][2] = 1 //黑子
chessMap[2][3] = 2 //蓝子
//2. 输出看看原始的数组
for _, v := range chessMap {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
//3. 转成稀疏数组
//思路
//(1). 遍历 chessMap, 如果我们发现有一个元素的值不为0,创建一个node结构体
//(2). 将其放入到对应的切片即可
var sparseArr []ValNode
//标准的一个稀疏数组应该还有一个 记录元素的二维数组的规模(行和列,默认值)
//创建一个ValNode 值结点
valNode := ValNode{
row: 11,
col: 11,
val: 0,
}
sparseArr = append(sparseArr, valNode)
for i, v := range chessMap {
for j, v2 := range v {
if v2 != 0 {
//创建一个ValNode 值结点
valNode := ValNode{
row: i,
col: j,
val: v2,
}
sparseArr = append(sparseArr, valNode)
}
}
}
//输出稀疏数组
fmt.Println("当前的稀疏数组是:::::")
for i, valNode := range sparseArr {
fmt.Printf("%d: %d %d %d\n", i, valNode.row, valNode.col, valNode.val)
}
//将这个稀疏数组,存盘 d:/chessmap.data
//如何恢复原始的数组
//1. 打开这个d:/chessmap.data => 恢复原始数组.
//2. 这里使用稀疏数组恢复
// 先创建一个原始数组
var chessMap2 [11][11]int
// 遍历 sparseArr [遍历文件每一行]
for i, valNode := range sparseArr {
if i != 0 { //跳过第一行记录值
chessMap2[valNode.row][valNode.col] = valNode.val
}
}
// 看看chessMap2 是不是恢复.
fmt.Println("恢复后的原始数据......")
for _, v := range chessMap2 {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
}
4. 队列(channel的本质就是队列)
4.1 队列的介绍
4.2 数组模拟队列
4.3 非环形队列
package main
import (
"fmt"
"os"
"errors"
)
//使用一个结构体管理队列
type Queue struct {
maxSize int
array [5]int // 数组=>模拟队列
front int // 表示指向队列首
rear int // 表示指向队列的尾部
}
//添加数据到队列
func (this *Queue) AddQueue(val int) (err error) {
//先判断队列是否已满
if this.rear == this.maxSize - 1 { //重要重要的提示; rear是队列尾部(含最后元素)
return errors.New("queue full")
}
this.rear++ //rear 后移
this.array[this.rear] = val
return
}
//从队列中取出数据
func (this *Queue) GetQueue() (val int, err error) {
//先判断队列是否为空
if this.rear == this.front { //队空
return -1, errors.New("queue empty")
}
this.front++
val = this.array[this.front]
return val ,err
}
//显示队列, 找到队首,然后到遍历到队尾
func (this *Queue) ShowQueue() {
fmt.Println("队列当前的情况是:")
//this.front 不包含队首的元素
for i := this.front + 1; i <= this.rear; i++ {
fmt.Printf("array[%d]=%d\t", i, this.array[i])
}
fmt.Println()
}
//编写一个主函数测试,测试
func main() {
//先创建一个队列
queue := &Queue{
maxSize : 5,
front : -1,
rear : -1,
}
var key string
var val int
for {
fmt.Println("1. 输入add 表示添加数据到队列")
fmt.Println("2. 输入get 表示从队列获取数据")
fmt.Println("3. 输入show 表示显示队列")
fmt.Println("4. 输入exit 表示显示队列")
fmt.Scanln(&key)
switch key {
case "add":
fmt.Println("输入你要入队列数")
fmt.Scanln(&val)
err := queue.AddQueue(val)
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("加入队列ok")
}
case "get":
val, err := queue.GetQueue()
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("从队列中取出了一个数=", val)
}
case "show":
queue.ShowQueue()
case "exit":
os.Exit(0)
}
}
}
4.4 环形队列
分析:
package main
import (
"fmt"
"errors"
"os"
)
//使用一个结构体管理环形队列
type CircleQueue struct {
maxSize int // 4
array [5]int // 数组
head int //指向队列队首 0
tail int //指向队尾 0
}
//入队列 AddQueue(push) GetQueue(pop)
//入队列
func (this *CircleQueue) Push(val int) (err error) {
if this.IsFull() {
return errors.New("queue full")
}
//分析出this.tail 在队列尾部,但是包含最后的元素
this.array[this.tail] = val //把值给尾部
this.tail = (this.tail + 1) % this.maxSize
return
}
//出队列
func (this *CircleQueue) Pop() (val int, err error) {
if this.IsEmpty() {
return 0, errors.New("queue empty")
}
//取出,head 是指向队首,并且含队首元素
val = this.array[this.head]
this.head = (this.head + 1) % this.maxSize
return
}
//显示队列
func (this *CircleQueue) ListQueue() {
fmt.Println("环形队列情况如下:")
//取出当前队列有多少个元素
size := this.Size()
if size == 0 {
fmt.Println("队列为空")
}
//设计一个辅助的变量,指向head
tempHead := this.head
for i := 0; i < size; i++ {
fmt.Printf("arr[%d]=%d\t", tempHead, this.array[tempHead])
tempHead = (tempHead + 1) % this.maxSize
}
fmt.Println()
}
//判断环形队列为满
func (this *CircleQueue) IsFull() bool {
return (this.tail + 1) % this.maxSize == this.head
}
//判断环形队列是空
func (this *CircleQueue) IsEmpty() bool {
return this.tail == this.head
}
//取出环形队列有多少个元素
func (this *CircleQueue) Size() int {
//这是一个关键的算法.
return (this.tail + this.maxSize - this.head ) % this.maxSize
}
func main() {
//初始化一个环形队列
queue := &CircleQueue{
maxSize : 5,
head : 0,
tail : 0,
}
var key string
var val int
for {
fmt.Println("1. 输入add 表示添加数据到队列")
fmt.Println("2. 输入get 表示从队列获取数据")
fmt.Println("3. 输入show 表示显示队列")
fmt.Println("4. 输入exit 表示显示队列")
fmt.Scanln(&key)
switch key {
case "add":
fmt.Println("输入你要入队列数")
fmt.Scanln(&val)
err := queue.Push(val)
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("加入队列ok")
}
case "get":
val, err := queue.Pop()
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("从队列中取出了一个数=", val)
}
case "show":
queue.ListQueue()
case "exit":
os.Exit(0)
}
}
}