Go语言数据结构(一)

一、稀疏数组
在这里插入图片描述
概念
当一个数组中大部分元素为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)
		}
	}
}

演示结果:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值