go语言队列的链式表示和实现


本文摘自网络,作者,侵删。

1、链队的定义

  • 队列(Queue)是一种先进先出的线性表,在表一段插入(表尾),在另一端(表头)删除。
    • 队头(Front),即表尾端
    • 队尾(Rear),即表头端
    • FIFO(First In First Out),即队列的操作具有先进先出的特性。
    • 相同,队列也是限定插入和删除只能在表的"端点"进行的线性表,故栈和队列是线性表的子集(是插入和删除位置受限的线性表)。
  • 链队列的操作与链表、链栈类似,当用户无法估计所用队列的长度,宜采用链队列。本文只给出以下操作的go语言实现。
    • 初始化
    • 入队
    • 出队

2、链队的初始化

//链式队列的数据结构
type queueNode struct {
    data interface{} // 存放数据
    next *queueNode // 存放指针
}

type queueList struct {
    length int //存储链表长度
    front *queueNode // 指向队头
    rear *queueNode // 指向队尾
}

//链队初始化
func initQueue() *queueList {
    L := &queueList{
        length: 0,
        front: nil,
        rear: nil,
    }
    return L
}

3、入队

//链队的入队
func (queue *queueList) push(val interface{}) {
    node := &queueNode{
        data: val,
        next: nil,
    }

    //处理空队
    if queue.isNull() {
        queue.front = node // 指向队头
        queue.rear = node
        queue.length ++
        return
    }

    queue.rear.next = node
    queue.rear = queue.rear.next
    queue.length ++
}

4、出队

//链队的出队
func (queue *queueList) pop() {
    // 判断队空
    if queue.isNull() {
        fmt.Println("队列为空")
        return
    }

    // 处理链队中只有一个结点的特殊情况
    if queue.length == 1 {
        queue.front = nil
        queue.rear = nil
        queue.length --
        return
    }

    queue.front = queue.front.next
    queue.length --
}

5、完整代码及结果演示

package main

import (
    "fmt"
)

//链式队列的数据结构
type queueNode struct {
    data interface{} // 存放数据
    next *queueNode // 存放指针
}

type queueList struct {
    length int //存储链表长度
    front *queueNode // 指向队头
    rear *queueNode // 指向队尾
}

//链队初始化
func initQueue() *queueList {
    L := &queueList{
        length: 0,
        front: nil,
        rear: nil,
    }
    return L
}

//链队的入队
func (queue *queueList) push(val interface{}) {
    node := &queueNode{
        data: val,
        next: nil,
    }

    //处理空队
    if queue.isNull() {
        queue.front = node // 指向队头
        queue.rear = node
        queue.length ++
        return
    }

    queue.rear.next = node
    queue.rear = queue.rear.next
    queue.length ++
}


//链队的出队
func (queue *queueList) pop() {
    // 判断队空
    if queue.isNull() {
        fmt.Println("队列为空")
        return
    }

    // 处理链队中只有一个结点的特殊情况
    if queue.length == 1 {
        queue.front = nil
        queue.rear = nil
        queue.length --
        return
    }

    queue.front = queue.front.next
    queue.length --
}

//判断队空
func (queue queueList) isNull() bool {
    return queue.length == 0
}


func (queue *queueList) Traverse() (arr []interface{}) {
    pre := queue.front
    for i := 0; i < queue.length; i++ {
        arr = append(arr, pre.data, "-->")
        pre = pre.next
    }
    return
}

func main() {
    data := []interface{}{
        "bala",
        12,
        33,
    }
    L := initQueue()
    for i := range data {
        L.push(data[i])
        fmt.Println(L.Traverse())
    }
    fmt.Println(L)
    L.pop()
    fmt.Println(L.Traverse())
    L.pop()
    fmt.Println(L.Traverse())
    L.pop()
    fmt.Println(L.Traverse())
    L.pop()
}
//输出
[bala -->]
[bala --> 12 -->]
[bala --> 12 --> 33 -->]
&{3 0xc0000044c0 0xc0000045a0}
[12 --> 33 -->]
[33 -->]
[]
队列为空

6、总结

在go语言中,现在能想到的队列相关应用是管道Channel的设计原理。
Channel 的收发操作均遵循了与队列类似的先进先出(FIFO)的设计,具体规则如下:

  • 先从 Channel 读取数据的 Goroutine 会先接收到数据;
  • 先向 Channel 发送数据的 Goroutine 会得到先发送数据的权利;

参考博客
Go 语言设计与实现


本文来自:简书

感谢作者:Zppj

查看原文:go语言队列的链式表示和实现

相关阅读 >>

手撸Golang etcd raft协议之3

我的个人能力发展报告(2015-2019)

Golang和erlang区别

Golang的zap怎么使用

Gocn酷Go推荐】Go程序配置利器-viper库

leetcode232 用栈实现队列 Golang

Go test

这家独角兽旅行服务公司,在用 Go 进行微服务治理

Go语言基础

Go - 实现项目内链路追踪(二)

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...