一、本节要掌握的问题
- 原始数组转稀疏数组
- 稀疏数组转原始数组
- 用数组模拟队列
- 数组模拟环形队列(队列优化)
二、内容详解
原始数组转稀疏数组
思路:创建存放node的切片——遍历chessMap——如果发现有元素不为0,将该元素存储为node,并放入切片。注意第一个node应该记录元素的规模等信息。
type Node struct {
row int
col int
val int
}
func main() {
//创建一个原始数组
var chessMap [11][11]int
chessMap[1][2] = 1 //黑子
chessMap[2][3] = 2 //蓝子
//输出原始数组
for _, v := range chessMap {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
//原始数组转稀疏数组
var nodeArr []Node
//创建头节点
node0 := Node{
11,
11,
0, //默认值
}
nodeArr = append(nodeArr, node0)
//遍历原始数组
for i, v := range chessMap {
for j, v2 := range v {
if v2 != 0 {
//存入nodeArr
node := Node{
i,
j,
v2,
}
nodeArr = append(nodeArr, node)
}
}
}
//输出稀疏数组
for i, v := range nodeArr {
fmt.Printf("%d:%d %d %d\n", i, v.row, v.col, v.val)
}
}
稀疏数组转原始数组
//稀疏数组转原始数组
//创建一个用来接收的原始数组
var chessMap2 [11][11]int
for i, v := range nodeArr {
//跳过头节点
if i != 0 {
chessMap2[v.row][v.col] = v.val
}
}
//输出原始数组
拓展:将稀疏数组存盘,然后从文件中读取数据转成原始数组。
用数组模拟队列
队列:队列是一个有序列表,可以用数组或是链表来实现。 数组遵循先入先出。
用数组来模拟队列我们需要创建一个结构体,给数组赋予一些功能和属性,将数组包装成一个队列。其用数组实现的原理如下图:
用front和rear着两个属性来标记队列的起始。其中rear是队列最后元素(rear指向的位置含元素),front是队列最前元素(front指向的位置不含元素)。
代码编写思路
- 向队列里添加数据时,rear+1,然后将数据放入rear指向的位置;向队列里取出数据时,front+1,然后取出front指向的数据。
- 当front==rear时,队列为空。
- 若rear==MaxSize-1,队列已满,无法存入数据。
代码演示
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 {
return errors.New("队列已满")
}
this.rear++
this.array[this.rear] = val
return
}
func (this *Queue) ShowQueue() {
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("队空")
}
this.front++
val = this.array[this.front]
return val, err
}
完整代码见文章末尾
package main
import (
"errors"
"fmt"
"log"
"os"
)
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 {
return errors.New("队列已满")
}
this.rear++
this.array[this.rear] = val
return
}
func (this *Queue) ShowQueue() {
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("队空")
}
this.front++
val = this.array[this.front]
return val, err
}
func main() {
queue := &Queue{
maxSize: 5,
front: -1,
rear: -1,
}
var k int
for {
fmt.Println("添加数据请按1")
fmt.Println("取出数据请按2")
fmt.Println("展示队列请按3")
fmt.Println("退出程序请按4")
fmt.Scan(&k)
switch k {
case 1:
fmt.Println("输入要添加的数据:")
var i int
fmt.Scan(&i)
err := queue.AddQueue(i)
if err != nil {
fmt.Println(err.Error())
}
case 2:
val, err := queue.GetQueue()
if err != nil {
log.Println("取数据出错:", err.Error())
}
fmt.Println("取出的数据是:", val)
case 3:
queue.ShowQueue()
case 4:
os.Exit(0)
}
}
}