使用go实现常见的数据结构

下面我将详细讲解使用go实现常见的数据结构的完整攻略。

1. 概述

数据结构是计算机程序设计中一个非常重要的概念,常见的有数组、链表、栈、队列、树、图等。本文主要介绍如何使用Go实现常见的数据结构。

2. 数组

数组是最简单、最基本的数据结构之一,它在Go中的实现非常简单,可以用以下代码片段表示:

// 定义一个长度为10的整型数组
var arr [10]int

// 初始化一个长度为5的整型数组
arr2 := [5]int{1, 2, 3, 4, 5}

需要注意的是,数组在定义时必须指定长度,且长度必须是一个常数。

3. 链表

链表是一种动态数据结构,它支持快速插入和删除操作。在Go中实现链表可以使用指针,以下为示例代码:

type Node struct {
    data int
    next *Node
}

// 初始化一个链表
var head *Node = new(Node)
head.next = nil

// 插入一个节点
newNode := new(Node)
newNode.data = 1
newNode.next = head.next
head.next = newNode

// 遍历链表
for pNode := head.next; pNode != nil; pNode = pNode.next {
    fmt.Println(pNode.data)
}

需要注意的是,链表中的数据类型可以是任意类型。

4. 栈

栈是一种后进先出(LIFO)的数据结构,通常用于表达式求值、括号匹配等问题。在Go中可以使用切片(slice)来实现栈,以下为示例代码:

// 定义一个栈结构体
type Stack struct {
    data []int
}

// 入栈
func (s *Stack) Push(x int) {
    s.data = append(s.data, x)
}

// 出栈
func (s *Stack) Pop() int {
    x := s.data[len(s.data)-1]
    s.data = s.data[:len(s.data)-1]
    return x
}

// 创建一个栈
s := new(Stack)

// 入栈
s.Push(1)
s.Push(2)
s.Push(3)

// 出栈
fmt.Println(s.Pop()) // 输出 3
fmt.Println(s.Pop()) // 输出 2
fmt.Println(s.Pop()) // 输出 1

需要注意的是,使用切片实现的栈需要注意初始容量,以提高性能。

5. 队列

队列是一种先进先出(FIFO)的数据结构,在Go中可以使用切片或链表来实现。以下为示例代码:

// 使用切片实现队列
type Queue struct {
    data []int
}

// 入队
func (q *Queue) Enqueue(x int) {
    q.data = append(q.data, x)
}

// 出队
func (q *Queue) Dequeue() int {
    x := q.data[0]
    q.data = q.data[1:]
    return x
}

// 使用链表实现队列
type Node struct {
    data int
    next *Node
}

type Queue struct {
    head *Node
    tail *Node
}

// 入队
func (q *Queue) Enqueue(x int) {
    newNode := new(Node)
    newNode.data = x
    newNode.next = nil

    if q.head == nil {
        q.head = newNode
        q.tail = newNode
    } else {
        q.tail.next = newNode
        q.tail = newNode
    }
}

// 出队
func (q *Queue) Dequeue() int {
    x := q.head.data
    q.head = q.head.next
    return x
}

需要注意的是,在使用链表实现队列时,需要维护队头和队尾指针。

6. 树

树是一种递归结构,它由节点和边组成,每个节点包含一个值和若干棵子树。在Go中可以使用结构体和指针来实现树,以下为示例代码:

// 定义一个二叉搜索树
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// 插入节点
func (root *TreeNode) Insert(x int) *TreeNode {
    if root == nil {
        return &TreeNode{Val: x}
    }

    if x < root.Val {
        root.Left = root.Left.Insert(x)
    } else if x > root.Val {
        root.Right = root.Right.Insert(x)
    }

    return root
}

// 构造一棵二叉搜索树
root := new(TreeNode)
root.Val = 3
root.Insert(1)
root.Insert(5)
root.Insert(4)
root.Insert(2)

// 中序遍历
var inorderTraversal func(root *TreeNode)
inorderTraversal = func(root *TreeNode) {
    if root != nil {
        inorderTraversal(root.Left)
        fmt.Println(root.Val)
        inorderTraversal(root.Right)
    }
}
inorderTraversal(root) // 输出 1 2 3 4 5

需要注意的是,在二叉搜索树中,左子树的所有节点都比根节点小,右子树的所有节点都比根节点大。

7. 图

图是一种复杂的数据结构,它由节点和边组成,每个节点包含一个值和一组邻接节点。在Go中可以使用邻接矩阵或邻接表来实现图。

// 使用邻接表实现图
type Graph struct {
    V      int       // 顶点数
    E      int       // 边数
    adj    [][]int   // 邻接表
    marked []bool    // 用于dfs的标记
}

// 添加一条边
func (g *Graph) AddEdge(v int, w int) {
    g.adj[v] = append(g.adj[v], w)
    g.adj[w] = append(g.adj[w], v)
    g.E++
}

// 深度优先搜索
func (g *Graph) DFS(v int) {
    g.marked[v] = true
    fmt.Println(v)
    for _, w := range g.adj[v] {
        if !g.marked[w] {
            g.DFS(w)
        }
    }
}

// 广度优先搜索
func (g *Graph) BFS(v int) {
    var queue []int
    queue = append(queue, v)
    g.marked[v] = true

    for len(queue) != 0 {
        v = queue[0]
        queue = queue[1:]
        fmt.Println(v)
        for _, w := range g.adj[v] {
            if !g.marked[w] {
                queue = append(queue, w)
                g.marked[w] = true
            }
        }
    }
}

// 构造一个图
g := new(Graph)
g.V = 5
g.adj = make([][]int, g.V)
g.marked = make([]bool, g.V)

g.AddEdge(0, 1)
g.AddEdge(0, 2)
g.AddEdge(1, 3)
g.AddEdge(1, 4)

// 深度优先遍历
fmt.Println("DFS:")
g.DFS(0)

// 广度优先遍历
fmt.Println("BFS:")
g.BFS(0)

需要注意的是,使用邻接表实现图需要用一个二维数组来保存每个节点的邻接节点。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用go实现常见的数据结构 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C++数据结构链表基本操作示例过程

    C++数据结构链表基本操作示例过程 链表是一种重要的数据结构,C++中链表的操作是非常常见的,下面我将详细介绍C++中链表的基本操作,包括创建链表、插入节点、删除节点和遍历链表等。 创建链表 首先,需要创建一个链表结构体,并定义节点类型struct Node,其中包含元素数据及下一个节点的指针。 struct Node { int data; Node* n…

    数据结构 2023年5月17日
    00
  • C++实现LeetCode(211.添加和查找单词-数据结构设计)

    首先,我们需要先了解一下题目的要求和限制,以及具体的解题思路。 题目描述 设计一个支持添加、删除、查找单词的数据结构。添加和删除单词的操作需要支持普通词和通配符’.’。查找单词只支持普通词,不支持通配符’.’。所有单词都是非空的。 解题思路 这道题可以使用前缀树(Trie树)来实现。 首先,我们需要定义一个单词类,它包含两个字段:单词字符串和单词长度。然后,…

    数据结构 2023年5月17日
    00
  • Lua教程(七):数据结构详解

    Lua教程(七):数据结构详解 Lua 中的数据结构广泛应用于各种计算机程序中。本文将详细介绍 Lua 中的数组、列表、栈、队列、集合和字典等数据结构的使用以及相关的函数。 数组 数组是存储在连续内存位置上的相同数据类型的元素集合。Lua 中的数组索引默认从 1 开始。下面是一些常用的 Lua 数组函数: table.concat(arr[, sep[, i…

    数据结构 2023年5月17日
    00
  • C语言数据结构与算法之时间空间复杂度入门

    C语言数据结构与算法之时间空间复杂度入门攻略 1. 什么是时间复杂度和空间复杂度? 在进行算法设计时,我们不仅需要考虑到算法的正确性,还要考虑到算法的执行效率。而衡量算法执行效率的指标主要有两个,即时间复杂度和空间复杂度: 时间复杂度:衡量算法所需时间的度量,通常用“大O”符号来表示。比如,对于n个元素的数组,某些算法需要执行n次操作,这个算法的时间复杂度就…

    数据结构 2023年5月16日
    00
  • 数据结构与算法大作业:走迷宫程序(C语言,DFS)(代码以及思路)

    好家伙,写大作业,本篇为代码的思路讲解   1.大作业要求 走迷宫程序 问题描述: 以一个 m * n 的长方阵表示迷宫, 0和1分别表示迷宫的通路和障碍。 设计一个程序, 对任意设定的迷宫, 求出一条从入口到出口的通路, 或得出没有通路的结论。 基本要求: (1) 实现一个以链表做存储的栈类型, 然后编写一个求解迷宫的非递归程序。 求的通路以三元组(i, …

    算法与数据结构 2023年5月9日
    00
  • Java数据结构之队列(动力节点Java学院整理)

    Java数据结构之队列(动力节点Java学院整理) 队列是一种有序列表,在其中所有插入操作必须在后端进行,而所有的删除操作必须在前端进行的数据结构。这种结构有时被称为先进先出(FIFO)。 队列的分类 普通队列:队列和栈一样,都是只能在一端进行插入操作,在另一端进行删除操作的特殊线性表。队列的特点是:先进先出。适用于数据必须按照插入顺序处理的必要场合。 双端…

    数据结构 2023年5月17日
    00
  • Unity接入高德开放API实现IP定位

    Unity接入高德开放API实现IP定位攻略 本文将详细介绍如何在Unity中接入高德开放API实现IP定位功能。 准备工作 在开始之前,需要准备以下内容: 高德开放平台账号 Unity集成开发环境 一台联网的电脑或手机 开始集成 1. 创建Unity项目 首先,我们需要在Unity中创建一个新的项目。 2. 导入AMap3D SDK 将下载好的AMap3D…

    数据结构 2023年5月17日
    00
  • c语言 数据结构实现之字符串

    下面是详细讲解“c语言 数据结构实现之字符串”的完整攻略。 1. 什么是字符串? 字符串是由一组字符组成的序列,字符可以是字母、数字、标点符号等,字符串常用于文本处理。 在C语言中,字符串是以‘\0’ 结束的字符数组。 2. 字符串的常见操作 常见的字符串操作包括:复制、比较、连接、查找等。 2.1 字符串复制 字符串复制是将一个字符串的内容复制到另一个字符…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部