golang数据结构与算法——稀疏数组、队列和链表


一 稀疏数组

1.1 先看一个实际的需求

编写的五子棋程序中,有存盘退出和续上盘的功能

在这里插入图片描述

因为该二维数组的很多值是默认值 0, 因此记录了很多没有意义的数据

1.2 稀疏数组基本介绍

当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方法是:

  1. 记录数组一共有几行几列,有多少个不同的值
  2. 思想:把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模

使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)

把稀疏数组存盘,并且可以从新恢复原来的二维数组数

1.3 稀疏数组举例说明

在这里插入图片描述

1.4 把数组转换为稀疏数组实现

思路分析:

在这里插入图片描述

代码实现:

package main

import (
	"bufio"
	"fmt"
	"os"
)

type ValNode struct {
   
	row int
	col int
	val int
}

func main() {
   
	filePath := "E:/golang开发学习/sparsearray.data"
	file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
   
		fmt.Printf("open file err=%v\n", err)
		return
	}
	//及时关闭file句柄
	defer file.Close()

	// 1. 创建一个原始数组
	var chessMap [11][11]int
	chessMap[1][2] = 1
	chessMap[2][3] = 2

	// 2. 输出查看原始数组
	fmt.Println("原始数组为:")
	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{
   
		row: 11,
		col: 11,
		val: 0,
	}

	sparseArr = append(sparseArr, ValNode)
	for i, v := range chessMap {
   
		for j, v1 := range v {
   
			if v1 != 0 {
   
				// 创建一个ValNode 值节点
				ValNode.row = i
				ValNode.col = j
				ValNode.val = v1
				sparseArr = append(sparseArr, ValNode)
			}
		}
	}

	// 4. 输出稀疏数组
	fmt.Println("当前的稀疏数组是:")
	writer := bufio.NewWriter(file)
	for _, ValNode := range sparseArr {
   
		var s1 = fmt.Sprintf("%d %d %d\n", ValNode.row, ValNode.col, ValNode.val)
		writer.WriteString(s1)
		fmt.Printf("%s", s1)
	}
	writer.Flush()
}

运行结果:

[Running] go run "e:\golang开发学习\go_pro\test.go"
原始数组为:
0	0	0	0	0	0	0	0	0	0	0	
0	0	1	0	0	0	0	0	0	0	0	
0	0	0	2	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
当前的稀疏数组是:
11 11 0
1 2 1
2 3 2

[Done] exited with code=0 in 1.255 seconds

E:/golang开发学习/sparsearray.data:

11 11 0
1 2 1
2 3 2

1.5 把稀疏数组还原为原数组

  1. 坑点一:读取后是字符串需要,分割成字符串数组,这里通过Split但是数组最后一个多一个换行符号需要去掉
  2. 坑点二:golang是无法直接在二维数组创建时传变量的。这个时候先声明一个二维切片。初始化二维切片后。填入初始值。

代码实现:

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

func main() {
   
	file, err := os.Open("E:/golang开发学习/sparsearray.data")
	if err != nil {
   
		fmt.Printf("打开文件出错:%v", err)
	}
	defer file.Close()
	
	reader := bufio.NewReader(file)
	str, err := reader.ReadString('\n')
	if err == io.EOF {
    //io.EOF 文件末尾
		fmt.Println("第一行 读取完毕")
	}
	// 分割字符串 通过空格
	arr := strings.Split(str, " ")
	m, _ := strconv.Atoi(arr[0])
	n, _ := strconv.Atoi(arr[1])
	v, err := strconv.Atoi(strings.Replace(arr[2], "\n", "", -1))
	if err != nil {
   
		// handle error
		fmt.Println(err)
		os.Exit(2)
	}
	// golang是无法直接在二维数组创建时传变量的 var chessMap [m][n]int 不能成功
	var chessMap [][]int
	for i := 0; i < m; i++ {
   
		arr1 := make([]int, n)            //创建一个一维切片
		chessMap = append(chessMap, arr1) //把一维切片,当作一个整体传入二维切片中
	}
	for i := 0; i < m; i++ {
   
		for j := 0; j < n; j++ {
   
			chessMap[i][j] = v
		}
	}

	for {
   
		str, err := reader.ReadString('\n') // 一次读到换行结束
		if err == io.EOF {
                     //io.EOF 文件末尾
			break
		}
		//输出内容
		arr := strings.Split(str, " ")
		m, _ := strconv.Atoi(arr[0])
		n, _ := strconv.Atoi(arr[1])
		v, _ := strconv.Atoi(strings.Replace(arr[2], "\n", "", -1))
		chessMap[m][n] = v
	}
	fmt.Println("稀疏数组还原成原数组:")
	for _, v := range chessMap {
   
		for _
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值