稀疏数组(sparsearray)
当一个数组中大部分元素为0,或者为同一个值的数组是,可以使用稀疏数组来保存该数组
处理方法:
记录数组一共有几行几列,有多少个不同的值
把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。
应用实例
使用稀疏数组,来保存二维数组
把稀疏数组存盘,并且可以恢复到原来的二维数组。
原始数组->稀疏数组
package main
import "fmt"
type ValNode 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()
}
// 转成稀疏数组 ->算法
// 1、便历数组,如果一个元素的值不为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, v2 := range v {
if v2 != 0 {
// 创建节点
valNode := ValNode{
row: i,
col: j,
val: v2,
}
sparseArr = append(sparseArr, valNode)
}
}
}
for i, valNode := range sparseArr {
fmt.Printf("%d:%d %d %d\n", i, valNode.row, valNode.col, valNode.val)
}
}
稀疏数组->原始数组
var chessMap2 [11][11]int
// 遍历 sparseArr
for i, valNode := range sparseArr {
// 记录第一行的值
if i != 0 {
chessMap2[valNode.row][valNode.col] = valNode.val
}
}
fmt.Println("恢复后的原始数据....")
for _, v := range chessMap2 {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
队列(queue)
队列是一个有序列表,可以使用数组或链表来实现
遵循先入先出的原则。
数组模拟队列
队列本身是有序列表,若使用数组的结构来存储队列的数据,需要一下声明,其中maxSize是队列的最大容量
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量front及rear分别及录队列的前后端的下标,front会随着数据输出二改变,而rear则是随着数据输入而改变
package main
import (
"errors"
"fmt"
"os"
)
type Queue struct {
maxSize int
array [5]int // 数组=>模拟队列
front int // 指向队列首
rear int // 只想对俄的尾
}
// 添加数据到队列
func (q *Queue) addQueue(val int) (err error) {
// 先判断队列是否已满
if q.rear == q.maxSize-1 {
return errors.New("queue full")
}
q.rear++
q.array[q.rear] = val
return
}
// 从队列中取出数据
func (q *Queue) GetQueue() (val int, err error) {
if q.rear == q.front {
return -1, errors.New("queue empty")
}
q.front++
val = q.array[q.front]
return val, err
}
func (q *Queue) ShowQueue() {
for i := q.front + 1; i <= q.rear; i++ {
fmt.Printf("array[%d] = %d\n", i, q.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("加入队列ok")
} else {
fmt.Println(err.Error())
}
case "get":
val, err := queue.GetQueue()
if err != nil {
fmt.Print(err.Error())
} else {
fmt.Println("从队列中去除了一个数=", val)
}
case "show":
queue.ShowQueue()
case "exit":
os.Exit(0)
}
}
}
数组模拟环形队列
package main
import (
"errors"
"fmt"
"os"
)
type CircleQueue struct {
maxSize int
array [5]int
head int // 指向队列队首
tail int // 指向队尾
}
func (q *CircleQueue) Push(val int) (err error) {
if q.IsFull() {
return errors.New("queue full")
}
q.array[q.tail] = val
q.tail = (q.tail + 1) % q.maxSize
return
}
func (q *CircleQueue) Pop() (val int, err error) {
if q.IsEmpty() {
return 0, errors.New("qieie empty")
}
// head指向队首,并且韩队首元素
val = q.array[q.head]
q.head++
return
}
// 显示队列
func (q *CircleQueue) ListQueue() {
size := q.Size()
if size == 0 {
fmt.Println("队列为空")
}
// 设计一个辅助变量
tempHead := q.head
for i := 0; i < size; i++ {
fmt.Printf("arr[%d]=%d\n", tempHead, q.array[tempHead])
tempHead = (tempHead + 1) % q.maxSize
}
}
// 判断环形队列为空
func (q *CircleQueue) IsFull() bool {
return (q.tail+1)%q.maxSize == q.head
}
func (q *CircleQueue) IsEmpty() bool {
return q.tail == q.head
}
func (q *CircleQueue) Size() int {
return (q.tail + q.maxSize - q.head) % q.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("加入队列ok")
} else {
fmt.Println(err.Error())
}
case "get":
val, err := queue.Pop()
if err != nil {
fmt.Print(err.Error())
} else {
fmt.Println("从队列中去除了一个数=", val)
}
case "show":
queue.ListQueue()
case "exit":
os.Exit(0)
}
}
}
链表
单链表
package main
import "fmt"
type LinkNode struct {
no int
name string
nickname string
next *LinkNode
}
// 编写第一种插入方法,在单链表的最后加入
func InsertHEroNode(head *LinkNode, newHeroNode *LinkNode) {
// 1.先找到该链表的最后这个节点
// 2.创建一个辅助节点
temp := head
for {
if temp.next == nil {
break
}
temp = temp.next
}
temp.next = newHeroNode
}
func ListHeroNode(head *LinkNode) {
temp := head
if temp.next == nil {
fmt.Println("空空如也。。。")
return
}
for {
fmt.Printf("[%d , %s, %s]==>", temp.next.no, temp.next.name, temp.next.nickname)
temp = temp.next
if temp.next == nil {
break
}
}
}
func main() {
// 创建一个头结点
head := &LinkNode{}
hero1 := &LinkNode{
no: 1,
name: "宋江",
nickname: "及时雨",
}
hero2 := &LinkNode{
no: 2,
name: "卢俊义",
nickname: "玉麒麟",
}
InsertHEroNode(head, hero1)
InsertHEroNode(head, hero2)
ListHeroNode(head)
}
单链表插入
package main
import "fmt"
type LinkNode struct {
no int
name string
nickname string
next *LinkNode
}
// 编写第一种插入方法,在单链表的最后加入
func InsertHeroNode(head *LinkNode, newHeroNode *LinkNode) {
// 1.先找到该链表的最后这个节点
// 2.创建一个辅助节点
temp := head
for {
if temp.next == nil {
break
}
temp = temp.next
}
temp.next = newHeroNode
}
func InsertHeroNode2(head *LinkNode, newHeroNode *LinkNode) {
temp := head
flag := true
for {
if temp.next == nil {
break
} else if temp.next.no > newHeroNode.no {
break
} else if temp.next.no == newHeroNode.no {
flag = false
break
}
temp = temp.next
}
if !flag {
fmt.Println("对不起,已经存在no=", newHeroNode.no)
return
} else {
newHeroNode.next = temp.next
temp.next = newHeroNode
}
}
func ListHeroNode(head *LinkNode) {
temp := head
if temp.next == nil {
fmt.Println("空空如也。。。")
return
}
for {
fmt.Printf("[%d , %s, %s]==>", temp.next.no, temp.next.name, temp.next.nickname)
temp = temp.next
if temp.next == nil {
break
}
}
}
func main() {
// 创建一个头结点
head := &LinkNode{}
hero1 := &LinkNode{
no: 1,
name: "宋江",
nickname: "及时雨",
}
hero2 := &LinkNode{
no: 2,
name: "卢俊义",
nickname: "玉麒麟",
}
hero3 := &LinkNode{
no: 3,
name: "林冲",
nickname: "豹子头",
}
InsertHeroNode2(head, hero1)
InsertHeroNode2(head, hero2)
InsertHeroNode2(head, hero3)
ListHeroNode(head)
}
单链表删除
package main
import "fmt"
type LinkNode struct {
no int
name string
nickname string
next *LinkNode
}
// 编写第一种插入方法,在单链表的最后加入
func InsertHeroNode(head *LinkNode, newHeroNode *LinkNode) {
// 1.先找到该链表的最后这个节点
// 2.创建一个辅助节点
temp := head
for {
if temp.next == nil {
break
}
temp = temp.next
}
temp.next = newHeroNode
}
func InsertHeroNode2(head *LinkNode, newHeroNode *LinkNode) {
temp := head
flag := true
for {
if temp.next == nil {
break
} else if temp.next.no > newHeroNode.no {
break
} else if temp.next.no == newHeroNode.no {
flag = false
break
}
temp = temp.next
}
if !flag {
fmt.Println("对不起,已经存在no=", newHeroNode.no)
return
} else {
newHeroNode.next = temp.next
temp.next = newHeroNode
}
}
func ListHeroNode(head *LinkNode) {
temp := head
if temp.next == nil {
fmt.Println("空空如也。。。")
return
}
for {
fmt.Printf("[%d , %s, %s]==>", temp.next.no, temp.next.name, temp.next.nickname)
temp = temp.next
if temp.next == nil {
break
}
}
}
func DelHerNode(head *LinkNode, id int) {
temp := head
flag := false
// 找到要删除的节点
for {
if temp.next == nil {
break
} else if temp.next.no == id {
flag = true
break
}
temp = temp.next
}
if flag {
temp.next = temp.next.next
} else {
fmt.Println("要删除的结点不存在")
}
}
func main() {
// 创建一个头结点
head := &LinkNode{}
hero1 := &LinkNode{
no: 1,
name: "宋江",
nickname: "及时雨",
}
hero2 := &LinkNode{
no: 2,
name: "卢俊义",
nickname: "玉麒麟",
}
hero3 := &LinkNode{
no: 3,
name: "林冲",
nickname: "豹子头",
}
InsertHeroNode2(head, hero1)
InsertHeroNode2(head, hero2)
InsertHeroNode2(head, hero3)
DelHerNode(head, 2)
ListHeroNode(head)
}