01稀疏数组的转换和队列|尚硅谷数据结构与算法笔记

106 阅读3分钟

一、本节要掌握的问题

  • 原始数组转稀疏数组
  • 稀疏数组转原始数组
  • 用数组模拟队列
  • 数组模拟环形队列(队列优化)

二、内容详解

原始数组转稀疏数组

思路:创建存放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]intfor i, v := range nodeArr {
        //跳过头节点
        if i != 0 {
            chessMap2[v.row][v.col] = v.val
        }
    }
​
    //输出原始数组

拓展:将稀疏数组存盘,然后从文件中读取数据转成原始数组。

用数组模拟队列

队列:队列是一个有序列表,可以用数组或是链表来实现。 数组遵循先入先出。

 用数组来模拟队列我们需要创建一个结构体,给数组赋予一些功能和属性,将数组包装成一个队列。其用数组实现的原理如下图:

image.png
 用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)
      }
   }
}