国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Go 中如何實現各種鏈表?

開發 后端
本文教程將說明在 Go 語言中如何借助指針和結構體類型來實現各種鏈表。

鏈表是動態內存分配中最常見的數據結構之一。它由一組有限的元素組成,每個元素(節點)至少占用兩塊內存:一塊用于存放數據,另一塊用于存放指向下一個節點的指針。

本文教程將說明在 Go 語言中如何借助指針和結構體類型來實現各種鏈表。

一、Go 中的數據結構

隨機存取存儲器(RAM)可以想象成一張由許多地址單元組成的表格、矩陣或網格。為了在這張表中存放數據,Go 程序員必須先把內存劃分成可定位的結構,并為它們起一個便于識別的名字——變量名。需要注意的是,變量名只是為了方便程序員閱讀;編譯后,名字會被實際的內存引用(例如 0x78BA 這樣的地址)替換。

最簡單的情況下,變量名只對應單個內存單元;復雜時,它可以代表一段連續空間,或是具有行和列的二維區域,也就是數組。數組可通過下標尋址,例如array_name[2][4]表示第二行第四列的元素。

再復雜一些,數據元素之間的結構關系可能并非連續存儲,而是隨機分布,比如用來表示層級關系的樹、分支結構,或含有多重連接的復雜網絡結構。

因此,為了存儲這些結構化關系,Go 開發者必須根據具體需求自行設計內存布局與訪問策略。

二、靜態 vs. 動態內存分配

在內存分配中,有兩個關鍵特性:靜態和動態。

  • 靜態數據結構的大小和存儲位置在編譯期就已確定;
  • 動態數據結構的大小和位置則未預定義,而是在運行時決定。

舉例來說,當 Go 開發者聲明一個數組時,需要提前給出固定長度,這樣編譯器才能在你使用下標時準確地定位內存地址。而在動態數據結構(例如鏈表)中,下一個數據節點的地址只有在程序執行、節點被創建時才會確定,因此整個結構可在運行期間自由增長或收縮。由于靜態結構存放在連續內存中,元素呈線性排列;動態結構則無此限制。

眾多動態數據結構的基礎——雖然動態分配并不限于此——就是鏈表。鏈表的各數據節點散布在內存的任意位置,通過指針相互連接。因此,一個鏈表節點至少包含兩部分:

  • 存放實際數據的元素
  • 指向下一節點的鏈接

三、順序存儲與鏈式存儲對比

與順序存儲結構(如數組)不同,鏈式存儲除了保存數據本身,還需要額外的內存來存放指向下一節點的鏈接。這在某些場景下會增加開銷,但鏈式存儲帶來的靈活性通常更具優勢。比如,數組的內存大小在創建時就固定,因此可能出現大量未被利用的空間;而鏈表只有在需要時才創建節點,不會浪費內存。

在鏈表中刪除元素非常容易,而順序存儲往往要移動大量數據才能完成刪除。同樣,鏈表插入元素也很高效。不過,如果要隨機訪問某個位置的元素,順序存儲則更快。

兩種存儲方式各有利弊,Go 程序員應根據具體需求選擇合適的數據結構。

四、鏈表的四種基本形態

鏈表在內存中的組織方式主要有四種:單向(線性)、循環、雙向以及雙向循環。

  • 單向(線性)鏈表:只有一個 next 指針指向下一個節點;最后一個節點的 next 為 nil。遍歷時一旦遇到 nil 就表示到達鏈表末尾;
  • 循環鏈表:結構與單向鏈表相同,但最后一個節點的 next 指向頭節點,因此尾部再向后訪問就回到起點,可形成“環形”遍歷;
  • 雙向鏈表:每個節點同時擁有 prev 與 next 兩個指針,分別指向前驅和后繼節點。這樣即可正向也可反向遍歷,查找元素更靈活;
  • 雙向循環鏈表:在雙向鏈表的基礎上,讓尾節點的 next 指向頭節點,頭節點的 prev 指向尾節點,于是可以向前或向后進行環形遍歷。

從單向到雙向、從線性到循環,鏈表的靈活性依次增強。下面的示例將演示在 Go 中實現這幾種鏈表(示例僅涵蓋鏈表的創建與遍歷,以保持簡潔)。

1. 單向鏈表示例

下面是一個在 Go 中創建單向鏈表的示例:

package main

import (
    "fmt"
    "math/rand"
)

type Node struct {
    info interface{}
    next *Node
}

type List struct {
    head *Node
}

func (l *List) Insert(d interface{}) {
    node := &Node{info: d}
    if l.head == nil {
        l.head = node
        return
    }
    p := l.head
    for p.next != nil {
        p = p.next
    }
    p.next = node
}

func Show(l *List) {
    for p := l.head; p != nil; p = p.next {
        fmt.Printf("-> %v ", p.info)
    }
}

func main() {
    sl := List{}
    for i := 0; i < 5; i++ {
        sl.Insert(rand.Intn(100))
    }
    Show(&sl)
}

示例輸出:

-> 81 -> 87 -> 47 -> 59 -> 81

2. 循環單向鏈表

我們可以輕松地把單向鏈表轉換為循環鏈表。無需修改上述代碼,只需再添加兩個函數:ConvertSinglyToCircular 和 ShowCircular,并在 main 函數中調用它們即可。以下是這兩個函數:

func ConvertSinglyToCircular(l *List) {
    if l.head == nil {
        return
    }
    p := l.head
    for p.next != nil {
        p = p.next
    }
    p.next = l.head
}

func ShowCircular(l *List) {
    p := l.head
    for {
        fmt.Printf("-> %v ", p.info)
        if p.next == l.head {
            break
        }
        p = p.next
    }
}

注意:雖然假設該鏈表已經是循環的(即 p.next 最終會指回 l.head),但如果 l.head 為 nil(空鏈表),此函數將發生空指針解引用錯誤并崩潰。

現在,在 main 函數中按如下方式調用這兩個函數:

func main() {
    sl := List{}
    for i := 0; i < 5; i++ {
        sl.Insert(rand.Intn(100))
    }
    ConvertSinglyToCircular(&sl)
    ShowCircular(&sl)
}

3. 雙向鏈表示例

下面是一個演示如何在 Go 中創建雙向鏈表的代碼示例:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

type Node struct {
    info interface{}
    prev *Node
    next *Node
}

type List struct {
    head *Node
    tail *Node
}

func (l *List) Insert(d interface{}) {
    node := &Node{info: d}
    if l.head == nil {
        l.head, l.tail = node, node
        return
    }
    l.tail.next = node
    node.prev = l.tail
    l.tail = node
}

func Show(l *List) {
    for p := l.head; p != nil; p = p.next {
        fmt.Printf("-> %v ", p.info)
    }
}

func ReverseShow(l *List) {
    for r := l.tail; r != nil; r = r.prev {
        fmt.Printf("-> %v ", r.info)
    }
}

func main() {
    sl := List{}
    rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
    for i := 0; i < 10; i++ {
        sl.Insert(rnd.Intn(100))
    }
    Show(&sl)
    fmt.Println("\n----------------------------")
    ReverseShow(&sl)
}

示例輸出:

-> 11 -> 17 -> 56 -> 71 -> 39 -> 44 -> 18 -> 78 -> 25 -> 19 
----------------------------
-> 19 -> 25 -> 78 -> 18 -> 44 -> 39 -> 71 -> 56 -> 17 -> 11

4. 雙向循環鏈表

與循環鏈表類似,雙向循環鏈表也可以很容易地由雙向鏈表轉換而來。我們只需在上述代碼中再添加兩個函數即可。其余代碼保持不變,只需在 main 函數中進行輕微修改,就像在前面的循環鏈表示例中所做的那樣:

func ConvertDoublyToDoublyCircular(l *List) {
    if l.head == nil || l.tail == nil {
        return
    }
    l.head.prev = l.tail
    l.tail.next = l.head
}

func ShowDoublyCircular(l *List) {
    p := l.head
    for {
        fmt.Printf("-> %v ", p.info)
        if p.next == l.head {
            break
        }
        p = p.next
    }
}

func ReverseShowDoublyCircular(l *List) {
    r := l.tail
    for {
        fmt.Printf("-> %v ", r.info)
        if r.prev == l.tail {
            break
        }
        r = r.prev
    }
}

main 示例:

func main() {
    sl := List{}
    rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
    for i := 0; i < 10; i++ {
        sl.Insert(rnd.Intn(100))
    }
    ConvertDoublyToDoublyCircular(&sl)
    ShowDoublyCircular(&sl)
    fmt.Println("\n----------------------------")
    ReverseShowDoublyCircular(&sl)
}

五、關于在 Go 中實現鏈表的最后思考

正如我們所見,在 Go 語言中實現鏈表相當簡單。鏈式分配可以用來表示各種類型的數據——無論是單個值,還是擁有眾多字段的復雜數據結構。

當配合指針進行順序查找時,訪問速度非常快。與鏈表相關的優化技巧也有不少。與單向鏈表相比,雙向鏈表效率更高,而且能夠在兩個方向上快速遍歷。

責任編輯:趙寧寧 來源: 令飛編程
相關推薦

2021-04-09 20:04:34

區塊鏈Go加密

2020-03-17 10:24:12

Go語言停止寫障礙

2011-08-12 14:04:53

iPhone動畫

2021-07-02 07:18:19

Goresults通道類型

2024-10-15 10:00:06

2021-07-09 12:37:31

GoPython編程語言

2024-03-19 14:15:48

Go程序os.Exit()

2017-11-16 15:25:54

Go語言算法代碼

2022-01-04 10:25:32

Go參數加載

2017-08-31 11:28:47

Slice底層實現

2023-09-27 23:24:50

C++鏈表

2021-09-26 06:43:09

TCP連接Go

2021-09-11 22:32:26

Go 綁定 Host

2021-06-09 07:15:20

Go枚舉技巧

2023-02-26 01:37:57

goORM代碼

2021-07-12 10:24:36

Go裝飾器代碼

2021-01-21 05:45:07

Go字數統計

2015-08-19 14:43:19

pighadoop

2020-02-16 12:05:35

javascript前端面試

2023-04-18 08:27:16

日志級別日志包
點贊
收藏

51CTO技術棧公眾號

欧美性猛交xxxx偷拍洗澡| 亚洲色图激情小说| 17c丨国产丨精品视频| 狠狠色丁香久久综合频道| 2019中文字幕在线免费观看| 欧美亚洲福利| 欧美精品一区二区不卡| 在线免费黄色| 色婷婷亚洲综合| 区一区二日本| 亚洲自拍偷拍麻豆| a视频免费看| 综合自拍亚洲综合图不卡区| 激情婷婷综合网| 久久影院午夜论| 中文字幕无码不卡免费视频| 国产精品一区在线| 国产女人18毛片| 国产精品一二一区| 国产欧美久久久久| 成人av网址在线| 欧美视频免费播放| 国产精品色哟哟| 三年片观看免费观看大全视频下载| 一区在线观看视频| 国外男同性恋在线看| 午夜成人免费视频| av网页在线| 亚洲第一页中文字幕| 中文字幕资源网在线观看免费| 亚洲乱码一区二区| 日韩免费大片| 91精品国产乱码久久久久久久久 | 91久久偷偷做嫩草影院| 女同性一区二区三区人了人一| 97中文在线观看| 鲁大师成人一区二区三区| 一区二区三区四区免费视频| 粉嫩av一区二区三区在线播放| 国产成人黄色片| 亚洲美女在线国产| wwwww在线观看免费视频| 精品毛片乱码1区2区3区| 色婷婷综合久久久中字幕精品久久| 欧美成人午夜激情| 99久久www免费| 图片区小说区区亚洲五月| 成人免费av在线| 99热手机在线观看| 欧美性高清videossexo| 美女在线视频免费| 81精品国产乱码久久久久久| 欧美精品三级| 国产911在线观看| 亚洲人成伊人成综合网小说| seseavlu视频在线| 中文字幕亚洲天堂| 亚洲香蕉视频| 欧美精品一区在线| 26uuu亚洲| www.成人.com| 日韩在线视频一区| 欧美伊人影院| 五月丁香综合缴情六月小说| 亚洲成在人线在线播放| 蜜桃视频在线观看播放| 26uuu日韩精品一区二区| 久久久久久9| 成人午夜激情| 亚洲精品久久久久中文字幕二区| 日韩欧美四区| 亚洲一区二区在线看| 亚洲色图欧美激情| 97天天综合网| 国产啪精品视频| 粉嫩aⅴ一区二区三区四区五区| 国产超碰在线| 日韩一区二区三区国产| 欧美日本一区| 男人亚洲天堂网| 欧美男男青年gay1069videost| 国产精品2023| 91制片厂免费观看| 日韩欧美在线免费| 亚洲精品影片| 中国老女人av| 欧美日韩一区二区欧美激情| 欧美精品中文字幕亚洲专区| 亚洲国产高清国产精品| 亚洲午夜精品久久久久久久久| 依依综合在线| 成人免费在线看片| 国产精品理论在线观看| 美女100%一区| 欧美韩国日本精品一区二区三区| 亚洲黄色免费电影| 四虎国产精品免费久久5151| 亚洲精品成人自拍| 色www精品视频在线观看| 亚洲人成精品久久久 | 中文字幕av一区| 久久亚洲欧美| 天堂av中文在线资源库| 91精品国产沙发| 99精品欧美一区二区三区小说| 日韩影视在线| 久久偷看各类wc女厕嘘嘘偷窃| 精品欧美激情精品一区| 美女亚洲一区| 4虎在线播放1区| 欧美高清激情视频| 成人一区二区三区中文字幕| 丰满诱人av在线播放| 精品久久精品久久| 色综合夜色一区| 久久国产小视频| 蜜桃视频中文字幕| 性色av一区二区三区红粉影视| 99天天综合性| 97久久网站| 91.com在线| 国产一区二区三区在线免费观看| 麻豆91在线看| 蜜桃视频m3u8在线观看| 99久re热视频精品98| 日韩电影网在线| 毛片av一区二区| av白虎一区| 久久久成人精品一区二区三区| 亚洲国产精品99| 精品一区二区精品| 在线观看网站免费入口在线观看国内 | 久久66热re国产| 国产探花在线观看| 日韩精品久久一区二区三区| 日韩一级高清毛片| 美女诱惑一区| 看黄在线观看| 欧美精品自拍视频| 久久福利视频网| 亚洲天堂2014| 99久久亚洲精品蜜臀| 99视频在线观看地址| 秋霞久久久久久一区二区| 精品久久人人做人人爽| 久久国产精品99久久人人澡| 欧美一区 二区 三区| 黑森林福利视频导航| 欧美国产日韩视频| 亚洲精品自拍动漫在线| 亚洲精品网址| 欧洲性视频在线播放| 日本人体一区二区| 欧美精品videos性欧美| 亚洲国产日韩在线一区模特| 在线观看亚洲| 热色播在线视频| 日韩一级在线免费观看| 欧洲中文字幕国产精品| 色嗨嗨av一区二区三区| 日本大胆欧美人术艺术动态| 亚洲狼人综合| 理论片在线观看理伦片| 久久精品国产99精品国产亚洲性色| 日韩免费在线观看| www.亚洲色图| 久久一区二区三区电影| heyzo一区| 1069男同网址| 欧美日韩精品一区| 欧美成人免费在线视频| 91黄色在线观看| 国产.精品.日韩.另类.中文.在线.播放| 精品精品国产三级a∨在线| 狠狠狠综合7777久夜色撩人| 国产av不卡一区二区| 97免费视频在线| 欧美人伦禁忌dvd放荡欲情| 成人午夜伦理影院| 亚洲人体av| 日韩成人在线一区| 国产在线观看网站| 成年人视频观看| 国产传媒一区| 欧美精品一区二区三区国产精品| 日本乱人伦一区| 97精品超碰一区二区三区| 欧美午夜久久| 婷婷视频一区二区三区| 日本在线免费看| 免费午夜视频在线观看| 国产伦精品一区二区三区照片| 精品国产一区二区三区久久狼黑人 | 欧美日韩国产综合新一区| 狠狠色丁香九九婷婷综合五月| 奇米亚洲欧美| 国产综合色在线观看| 成人在线观看一区| 四色永久网址| 97在线国产视频|