一、稀疏数组
概念
当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:记录数组一共有几行几列,有多少个不同值;把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
如下图:左边是原始数组,右边是稀疏数组
ps:以上概念摘自于https://blog.csdn.net/weixin_45681935/article/details/108917276?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164034733316780357229156%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164034733316780357229156&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-108917276.pc_search_all_es&utm_term=%E7%A8%80%E7%96%8F%E6%95%B0%E7%BB%84&spm=1018.2226.3001.4187
下面,我们用Go语言实现原始数组转稀疏数组。
第一步,先创建一个原始数组:
package main
import "fmt"
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()
}
}
找到项目文件夹的根目录,输入cmd
在cmd中输入 go run main.go,得到原始数组:
//3.转成一个稀疏数组
//思路->
//1.遍历chessMap,如果我们发现有一个元素的值不等于0,我们就创建一个node结构体,
//2.将其放入到对应的切片即可
var sparseArr[]ValNode
//标准的一个稀疏数组应该还有表示记录原始的二维数组的规模(行和列,默认值)
//创建一个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)
}
}
符合结果:
第零个数是在第一行第二列,数值为1,第一个数是在第二行第三列,数值是2。
将稀疏数组转换成原始数组:
1.将这个稀疏数组,存盘 d:/chessmap.data
如何恢复原始的数组
2.打开这个d:/chessmap.data=>回复原始数组
3.这里使用稀疏数组恢复
for _,valNode :=range sparseArr{
chessMap2[valNode.row][valNode.col]=valNode.val
}
//先创建一个原始数组
//遍历 sprseArr [遍历文件每一行]
fmt.Println("恢复后的原始数组")
for _,v:=range chessMap2 {
for _,v2:=range v {
fmt.Printf("%d\t",v2)
}
fmt.Println()
}
}
二、使用数组模拟队列
队列介绍
队列是一个有序列表,可以用数组或者链表实现
遵循先进先出的原则:先存入队列的数据,要先取出,后存入的数据,要后取出
使用数组模拟队列示意图
数组模拟队列思路:
队列本身是有序列表,如果使用数组的结构来存储队列的数据,则队列数组的声明如上图,maxSize是队列的最大容量。
因为队列的的输出、输入分别从前后端来处理,所以需要两个变量fornt个rear分别记录前后端的下标,front会随着数据输出而改变,而rear会随着数据输入而改变。
当我们将数据存入队列时成为addQueue,addQueue有两个步骤。
<1.将为指针往后移rear++
<2.若尾指针rear小于队列的最大下标maxSize,则将数据存入rear所指的数组元素中,否则无法存入数据。
rear==maxSize-1 则对列为满
个人理解
存值得时候rear后移,取值的时候front后移,初始值都为-1
所以存的方式为 arr[++rear]=i;//从arr的第一个索引开始存
取的方式为return arr[++front];//从第一个索引开始取(先进先出)
获取头部数据的方式为 return arr[front+1] //因为front是指向队列的前一个位置
————————————————
以上概念摘自:
原文链接:https://blog.csdn.net/jefferyfg/article/details/101274903
顺序队列实现:
代码:
package main
import (
"errors"
"fmt"
"os"
)
type Queue struct {
maxSize int
array [4]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++
this.array[this.rear]=val
return
}
//显示队列,找到队首,然后遍历到队尾
//
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(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 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)
}
}
}
演示结果: