Golang学习 Day_15 数据结构01

稀疏数组(sparsearray)

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

处理方法:

  1. 记录数组一共有几行几列,有多少个不同的值

  1. 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。

应用实例

  1. 使用稀疏数组,来保存二维数组

  1. 把稀疏数组存盘,并且可以恢复到原来的二维数组。

原始数组->稀疏数组

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)

队列是一个有序列表,可以使用数组或链表来实现

遵循先入先出的原则。

数组模拟队列

  1. 队列本身是有序列表,若使用数组的结构来存储队列的数据,需要一下声明,其中maxSize是队列的最大容量

  1. 因为队列的输出、输入是分别从前后端来处理,因此需要两个变量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)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值