go语言结构体实现数据结构队列(先进先出)存储数据(逐行注释)

发布于:2024-12-18 ⋅ 阅读:(66) ⋅ 点赞:(0)

正在学习go语言中,欢迎提出宝贵意见

import (
	"fmt"
	"sync"
)

// 数据队列以链表的形式存储数据,每个节点存储一个任意类型的数据,
// 创建数据队列、添加数据、删除数据、获取队列长度,每个数据存储在一个节点中。
// 先进先出

// 数据节点
type DataNode struct {
	data interface{} // 节点中的数据
	next *DataNode   // 指向下一个节点
}

// 数据队列,存贮数据节点
type WorkQueue struct {
	root  *DataNode  // 指向头结点
	size  int        // 队列长度
	mutex sync.Mutex // 锁
}

// 创建数据队列
func NewWorkQueue() *WorkQueue {
	wq := &WorkQueue{root: nil, size: 0}
	return wq
}

// 数据入队
// 切片数据:wq.Add([]string{"aaa", "bbb"})
// 字符串数据:wq.Add("ccc")
// 字典数据:wq.Add(map[string]string{"a": "aa", "b": "bb"})
func (wq *WorkQueue) Add(data interface{}) {
	wq.mutex.Lock()         // 加锁
	defer wq.mutex.Unlock() // 解锁
	if wq.root == nil {     // 队列为空
		wq.root = new(DataNode) // 创建节点,赋值给头节点
		wq.root.data = data     // 节点数据赋值
	} else {
		dn := new(DataNode)    // 创建节点
		dn.data = data         // 节点数据赋值
		node := wq.root        // 获取队列头节点
		for node.next != nil { // 从头节点开始向下寻找尾节点
			node = node.next // 有下一个节点时,将下一个节点置为当前节点
		}
		node.next = dn // 将新节点连接到最后一个节点位置
	}
	wq.size++ // 数据队列长度+1
}

// 获取队首数据,并从队列中删除节点。
// 返回数据可能为nil,使用前需判断过滤nil值。
func (wq *WorkQueue) Pop() interface{} {
	wq.mutex.Lock()         // 加锁
	defer wq.mutex.Unlock() // 解锁
	if wq.root == nil {     // 数据队列为空
		return nil
	} else {
		node := wq.root     // 获取首节点
		v := node.data      // 获取首节点数据
		wq.root = node.next // 首节点设置为第二个节点
		wq.size--           // 数据队列长度-1
		return v            // 返回首节点数据
	}
}

// 获取数据队列长度
func (wq *WorkQueue) Size() int {
	return wq.size
}

// 遍历输出所有数据
func (wq *WorkQueue) ShowValue() {
	if wq.root == nil { // 队列为空
		fmt.Println("队列为空队列!")
	} else {
		size := wq.size
		fmt.Println("队列元素数:", size)
		node := wq.root // 获取队列头节点
		n := 1
		fmt.Printf("第%d个元素是:%v\n", n, node.data)
		for node.next != nil { // 从头节点开始向下寻找尾节点
			node = node.next // 有下一个节点时,将下一个节点置为当前节点
			n++
			fmt.Printf("第%d个元素是:%v\n", n, node.data)
		}
	}
}

网站公告

今日签到

点亮在社区的每一天
去签到