婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 詳解go語言單鏈表及其常用方法的實現

詳解go語言單鏈表及其常用方法的實現

熱門標簽:江蘇呼叫中心外呼系統有效果嗎 地圖區域圖標注后導出 赤峰電銷 貴州電話智能外呼系統 杭州人工智能電銷機器人費用 谷歌美發店地圖標注 利用地圖標注位置 400開頭電話怎樣申請 官渡電銷外呼管理系統怎么收費

目的

在刷算法題中經常遇到關于鏈表的操作,在使用go語言去操作鏈表時不熟悉其實現原理,目的是為了重溫鏈表這一基礎且關鍵的數據結構。

1、鏈表的特點和初始化

1.1、鏈表的特點
用一組任意的存儲單元存儲線性表的數據元素(這組存儲單元可以是連續的,也可以是不連續的)

1.2、結點

結點(node)

  • 數據域 => 存儲元素信息
  • 指針域 => 存儲結點的直接后繼,也稱作指針或鏈

首元結點 是指鏈表中存儲的第一個數據元素的結點
頭結點 是在首元結點之前附設的一個結點,其指針域指向首元結點(非必須)
頭指針 是指向鏈表中第一個結點的指針


1.3、單鏈表
特點

  • 每個結點中只包含一個指針域
  • 單鏈表是非隨機存取的存儲結構,要取得第i個數據元素必須從頭指針出發,順鏈進行尋找,也稱為順序存取的存取結構

1.4、單鏈表的常用操作

本文主要實現了單鏈表的以下操作

  • 判斷是否為空
  • 獲取鏈表長度
  • 在頭部插入元素
  • 在尾部插入元素
  • 刪除指定位置元素
  • 刪除指定值的元素
  • 查找是否包含指定值
  • 查找指定位置元素的值
  • 遍歷鏈表所有結點

1.5、單鏈表的初始化

//定義單鏈表結構體
type Node struct {
  data interface{} //數據域
  next *Node    //指針域
}
type List struct {
  length  int //儲存鏈表的長度
  headNode *Node
}

/*單鏈表的初始化
1、生成新結點作為頭結點,用頭指針指向頭結點
2、頭結點的指針域置空
*/
func InitList() *List {
  //即構造一個空的單鏈表L(包含頭指針)
  node := new(Node)
  L := new(List)
  L.headNode = node
  return L
}

2、單鏈表的插入

先講單鏈表的插入有利于后續相關操作的實現

2.1、在指定位置插入元素

/*單鏈表的插入=>將值為e的新結點插入到表的第i個結點的位置上,即插入到結點a(i-1)與a(i)之間
1、查找結點a(i-1)并由指針p指向該結點
2、生成一個新結點*s
3、將新結點*s的數據域置為e
4、將新結點*s的指針域指向結點a(i)
5、將結點*p的指針域指向新結點*s
*/
func (list *List) InsertElem(index int, v interface{}) {
  if index = 0 || index > list.length {
    fmt.Println("err")
  } else {
    pre := list.headNode
    node := Node{data: v}
    if index == 1 {
      node.next = pre
      list.headNode = node
    } else {
      for count := 1; count  index-1; count++ {
        pre = pre.next
      }
      node.next = pre.next
      pre.next = node
    }
    list.length--
  }
}

2.2、在頭部插入元素

func (list *List) AddElem(v interface{}) {
  node := Node{data: v}
  if list.IsNull() { //處理空表的插入,否則會導致一個空的頭結點后移
    list.headNode = node
    list.length++
    return
  }
  node.next = list.headNode
  list.headNode = node
  list.length++
  return
}

2.3、在尾部插入元素

func (list *List) AppendElem(v interface{}) {
  node := Node{data: v}
  if list.IsNull() {
    list.headNode.next = node
  } else {
    cur := list.headNode
    for cur.next != nil {
      cur = cur.next
    }
    cur.next = node
  }
  list.length++
  return
}

3、單鏈表的刪除

3.1、刪除指定值的元素

/*單鏈表的刪除
1、查找結點a(i-1)并由指針p指向該結點
2、臨時保存待刪除結點a(i)的地址在q中,以備釋放
3、將結點*p的指針域指向a(i)的直接后繼結點
4、釋放結點a(i)的空間
*/
func (list *List) DeleteElem(index int) {
  if index = 0 || index > list.length {
    fmt.Println("刪除位置不合理")
    return
  } else {
    pre := list.headNode
    if index == 1 {
      list.headNode = pre.next
    } else {
      pre := list.headNode
      for count := 1; count  index-1; count++ {
        pre = pre.next
      }
      pre.next = pre.next.next
    }
    list.length--
  }
}

3.2、刪除指定位置的元素

func (list *List) RemoveElem(v interface{}) {
  pre := list.headNode
  if pre.data == v {
    list.headNode = pre.next
    fmt.Println("ok")
  } else {
    for pre.next != nil {
      if pre.next.data == v {
        pre.next = pre.next.next
        fmt.Println("ok")
        return
      } else {
        pre = pre.next
      }
    }
    fmt.Println("fail")
    return
  }
}

4、單鏈表的查詢

4.1、查找是否包含指定值

/*單鏈表的按值查找
1、用指針p指向首元結點
2、從首元結點開始以此順著鏈域next向下查找,只要指向當前結點的指針p不為空,
并且p所指結點的數據域不等于給定值e,則執行以下操作:p指向下一個結點
3、返回p。若查找成功,p此時即為結點的地址值,若查找失敗,p的值即為NULL。
*/
func (list *List) LocateElem(v interface{}) bool {
  if IsNull() {
    fmt.Println("err")
  } else {
    pre := list.headNode
    for pre != nil {
      if pre.data == v {
        return true
      }
      pre = pre.next
    }
    return false
  }
}

4.2、查找指定位置的值

/*單鏈表的取值
1、用指針P指向首元結點,用j做計數器初值賦為1
2、從首元結點開始依次順著鏈域(指針域)next向下訪問,
只要指向當前結點的指針P不為空,并且沒有達到序號為i的結點,則循環執行以下操作:
  2.1、P指向下一個結點
  2.2、計數器j相應加1
3、退出循環時,如果指針P為空,或者計數器j大于i,說明指定的序號i值不合法(i大于表長n或i小于等于0),
取值失敗返回ERROR;否則取值成功,
此時j==i時,P所指的結點就是要找的第i個結點,用參數e保存當前結點的數據域,返回OK
*/
func (list *List) GetElem(index int) int {
  if index = 0 || index > list.length {
    fmt.Println("err")
    return
  } else {
    pre := list.headNode
    for j := 0; j  index; j++ {
      if pre != nil {
        pre = pre.next
      }
    }
    return pre.data
  }
}

4.3、遍歷單鏈表

func (list *List) ShowList() {
  if !list.IsNull() {
    cur := list.headNode
    for {
      fmt.Printf("\t%v", cur.data)
      if cur.next != nil {
        cur = cur.next
      } else {
        break
      }
    }
  }
}

5、完整代碼及結果展示

package main

import "fmt"

//定義單鏈表結構體

type Node struct {
  data interface{} //數據域
  next *Node    //指針域
}
type List struct {
  length  int //儲存鏈表的長度
  headNode *Node
}

/*
type Method interface {
  IsNull() bool          //1、判斷是否為空
  GetLength() int         //2、獲取鏈表長度
  InsertElem(i int, v interface{}) //3、在指定位置添加元素
  AddElem(v interface{})      //4、在頭部插入元素
  AppendElem(v interface{})    //5、在尾部插入元素
  DeleteElem(i int)        //6、刪除指定位置元素
  RemoveElem(v interface{})    //7、刪除指定值的元素
  ContaineElem(v interface{}) bool //8、是否包含指定值的元素
  LocateElem(i int) interface{}  //9、查找指定位置元素的值
  ShowList()            //10、遍歷鏈表所有結點
}
*/
/*單鏈表的初始化
1、生成新結點作為頭結點,用頭指針指向頭結點
2、頭結點的指針域置空
*/
func InitList() *List {
  //即構造一個空的單鏈表L(包含頭指針)
  node := new(Node)
  L := new(List)
  L.headNode = node
  return L
}

/*單鏈表的取值
1、用指針P指向首元結點,用j做計數器初值賦為1
2、從首元結點開始依次順著鏈域(指針域)next向下訪問,只要指向當前結點的指針P不為空,
并且沒有達到序號為i的結點,則循環執行以下操作:
  2.1、P指向下一個結點
  2.2、計數器j相應加1
3、退出循環時,如果指針P為空,或者計數器j大于i,說明指定的序號i值
不合法(i大于表長n或i小于等于0),取值失敗返回ERROR;否則取值成功,
此時j==i時,P所指的結點就是要找的第i個結點,用參數e保存當前結點的數據域,返回OK
*/
func (list *List) GetElem(index int) int {
  if index = 0 || index > list.length {
    return 0
  } else {
    pre := list.headNode
    for j := 0; j  index-1; j++ {
      if pre != nil {
        pre = pre.next
      }
    }
    return pre.data.(int)
  }
}

/*單鏈表的按值查找
1、用指針p指向首元結點
2、從首元結點開始以此順著鏈域next向下查找,只要指向當前結點的
指針p不為空,并且p所指結點的數據域不等于給定值e,則執行以下操作:
  2.1、p指向下一個結點
3、返回p。若查找成功,p此時即為結點的地址值,若查找失敗,p的值即為NULL。
*/
func (list *List) LocateElem(v interface{}) bool {
  if list.IsNull() {
    fmt.Println("err")
    return false
  } else {
    pre := list.headNode
    for pre != nil {
      if pre.data == v {
        return true
      }
      pre = pre.next
    }
    return false
  }
}

/*單鏈表的插入=>將值為e的新結點插入到表的第i個結點的位置上,即插入到結點a(i-1)與a(i)之間
1、查找結點a(i-1)并由指針p指向該結點
2、生成一個新結點*s
3、將新結點*s的數據域置為e
4、將新結點*s的指針域指向結點a(i)
5、將結點*p的指針域指向新結點*s
*/
func (list *List) InsertElem(index int, v interface{}) {
  if index = 0 || index > list.length {
    fmt.Println("err")
  } else {
    pre := list.headNode
    node := Node{data: v}
    if index == 1 {
      node.next = pre
      list.headNode = node
    } else {
      for count := 1; count  index-1; count++ {
        pre = pre.next
      }
      node.next = pre.next
      pre.next = node
    }
    list.length--
  }
}

/*單鏈表的刪除
1、查找結點a(i-1)并由指針p指向該結點
2、臨時保存待刪除結點a(i)的地址在q中,以備釋放
3、將結點*p的指針域指向a(i)的直接后繼結點
4、釋放結點a(i)的空間
*/
func (list *List) DeleteElem(index int) {
  if index = 0 || index > list.length {
    fmt.Println("刪除位置不合理")
    return
  } else {
    pre := list.headNode
    if index == 1 {
      list.headNode = pre.next
    } else {
      pre := list.headNode
      for count := 1; count  index-1; count++ {
        pre = pre.next
      }
      pre.next = pre.next.next
    }
    list.length--
  }
}

func (list *List) RemoveElem(v interface{}) {
  pre := list.headNode
  if pre.data == v {
    list.headNode = pre.next
  } else {
    for pre.next != nil {
      if pre.next.data == v {
        pre.next = pre.next.next
        return
      } else {
        pre = pre.next
      }
    }
    fmt.Println("fail")
    return
  }
}

func (list *List) IsNull() bool {
  if list.length == 0 {
    return true
  } else {
    return false
  }
}

func (list *List) AddElem(v interface{}) {
  node := Node{data: v}
  if list.IsNull() { //處理空表的插入,否則會導致一個空的頭結點后移
    list.headNode = node
    list.length++
    return
  }
  node.next = list.headNode
  list.headNode = node
  list.length++
  return
}

func (list *List) AppendElem(v interface{}) {
  node := Node{data: v}
  if list.IsNull() {
    list.headNode.next = node
  } else {
    cur := list.headNode
    for cur.next != nil {
      cur = cur.next
    }
    cur.next = node
  }
  list.length++
  return
}

func (list *List) ShowList() {
  if !list.IsNull() {
    cur := list.headNode
    for {
      fmt.Printf("\t%v", cur.data)
      if cur.next != nil {
        cur = cur.next
      } else {
        break
      }
    }
    fmt.Printf("\n")
  }
}

func main() {
  L := InitList()
  msg := []int{12, 5, 3, 8, 55, 13}
  for i := range msg {
    L.AddElem(msg[i])
  }
  fmt.Println("---- 添加元素 ----")
  L.AppendElem(66)
  L.ShowList()
  fmt.Println("---- 按位刪除元素 ----")
  L.DeleteElem(3)
  L.ShowList()
  fmt.Println("---- 按值刪除元素 ----")
  L.RemoveElem(13)
  L.ShowList()
  fmt.Println("---- 插入元素 ----")
  L.InsertElem(1, 88)
  L.ShowList()
  fmt.Println("---- 按值尋找元素 ----")
  fmt.Println(L.LocateElem(88))
  fmt.Println("---- 按位尋找元素 ----")
  fmt.Println(L.GetElem(4))
}

結果
---- 添加元素 ----
        13      55      8       3       5       12      66
---- 按位刪除元素 ----
        13      55      3       5       12      66
---- 按值刪除元素 ----
        55      3       5       12      66
---- 插入元素 ----
        88      55      3       5       12      66
---- 按值尋找元素 ----
true
---- 按位尋找元素 ----
5

6、總結

本文中除了初始化時為鏈表添加了一個空的頭結點,其他情況下均無頭結點,正如書中所說,為單鏈表添加頭結點會方便很多,對鏈表進行相關操作時,不需要對首元結點做額外的處理,也便于對空表和非空表做統一處理
關于刪除時釋放結點空間及指針回收,我們交由go強大的垃圾回收來完成

參考博客
Golang之單鏈表實現
go語言實現單鏈表

到此這篇關于詳解go語言單鏈表及其常用方法的實現的文章就介紹到這了,更多相關go語言單鏈表內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • python/golang 刪除鏈表中的元素
  • python/golang實現循環鏈表的示例代碼
  • Go實現雙向鏈表的示例代碼
  • golang雙鏈表的實現代碼示例
  • Go語言單鏈表實現方法
  • go實現反轉鏈表

標簽:松原 泰安 黔西 宜春 武漢 河池 保定 鷹潭

巨人網絡通訊聲明:本文標題《詳解go語言單鏈表及其常用方法的實現》,本文關鍵詞  詳解,語言,單鏈表,及其,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳解go語言單鏈表及其常用方法的實現》相關的同類信息!
  • 本頁收集關于詳解go語言單鏈表及其常用方法的實現的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    97国产一区二区| 91麻豆免费在线观看| 不卡视频在线看| 国产精品国产精品国产专区不蜜| 国产黄人亚洲片| 国产蜜臀97一区二区三区| 成人app网站| 最近日韩中文字幕| 欧洲另类一二三四区| 亚洲6080在线| 日韩视频一区二区三区 | 日韩一区二区三区视频在线观看| 亚洲伊人伊色伊影伊综合网| 777精品伊人久久久久大香线蕉| 免费成人你懂的| 国产免费成人在线视频| 色婷婷av一区二区三区软件| 欧美aaa在线| 欧美国产成人精品| 欧美在线|欧美| 国产一区免费电影| 亚洲尤物在线视频观看| 欧美精品v国产精品v日韩精品| 久久不见久久见免费视频7| 国产日韩一级二级三级| 91久久国产最好的精华液| 蜜臀av一区二区三区| 国产精品国产精品国产专区不片| 91精品在线观看入口| 99re视频这里只有精品| 免费国产亚洲视频| 亚洲在线观看免费| 蜜臀精品一区二区三区在线观看| 久久精品一区二区三区不卡牛牛| 欧美最新大片在线看| 国产精品88av| 蜜臀久久99精品久久久画质超高清| 亚洲欧美日韩在线播放| 精品久久久久久久一区二区蜜臀| 在线一区二区三区| 成人av资源站| 国产成人av电影免费在线观看| 亚洲va欧美va人人爽| 日韩美女视频一区二区| 久久久亚洲综合| 精品久久久久久久久久久院品网 | 一区二区三区资源| 欧美激情一区二区三区在线| 日韩欧美国产小视频| 欧美亚洲高清一区| 色哟哟在线观看一区二区三区| 成人一级视频在线观看| 国产精品中文字幕日韩精品| 美日韩黄色大片| 亚洲激情自拍视频| 亚洲精品老司机| 亚洲精品少妇30p| 夜夜嗨av一区二区三区网页| 亚洲免费在线视频一区 二区| 欧美高清在线精品一区| 国产精品久久久久久久久果冻传媒 | 国产午夜精品久久久久久免费视 | 欧美这里有精品| av一区二区三区黑人| 成人中文字幕在线| a4yy欧美一区二区三区| 91欧美一区二区| 欧美日韩日本视频| 欧美一区三区二区| 精品av久久707| 欧美激情中文不卡| 国产精品久久久久久户外露出| 激情六月婷婷综合| 极品少妇xxxx偷拍精品少妇| 韩国午夜理伦三级不卡影院| 国产毛片一区二区| 97精品国产露脸对白| 欧美日韩高清在线| 日韩视频一区二区三区| 国产欧美一区二区精品仙草咪| 中文字幕电影一区| 亚洲欧美偷拍卡通变态| 天天做天天摸天天爽国产一区| 青青草国产精品亚洲专区无| 国产一区 二区 三区一级| 成人高清免费观看| 欧美精品在线视频| 国产视频911| 亚洲一区二区av在线| 男女性色大片免费观看一区二区 | 成人激情校园春色| 欧美伊人久久大香线蕉综合69| 欧美一区三区四区| 中文字幕在线播放不卡一区| 亚洲大片精品永久免费| 国产美女主播视频一区| 在线观看一区二区视频| 精品电影一区二区三区| **网站欧美大片在线观看| 日韩在线一区二区三区| 成人黄色国产精品网站大全在线免费观看| 色乱码一区二区三区88 | 欧美成人精品3d动漫h| 亚洲欧洲日韩在线| 国内久久精品视频| 欧美中文一区二区三区| 国产精品无人区| 爽爽淫人综合网网站| 91性感美女视频| 精品久久99ma| 午夜欧美在线一二页| jvid福利写真一区二区三区| 日韩视频在线观看一区二区| 亚洲嫩草精品久久| 国产成人av电影在线观看| 正在播放亚洲一区| 亚洲国产精品一区二区久久恐怖片| 国产精品小仙女| 欧美一区二区二区| 午夜精品久久久久久久 | 91亚洲精品一区二区乱码| 精品国产伦一区二区三区观看体验| 亚洲区小说区图片区qvod| 国产成a人亚洲精| 91麻豆精品国产91久久久久| 国产九色精品成人porny| 精品欧美乱码久久久久久 | 成人小视频在线观看| 一区二区激情小说| 中文av字幕一区| 91精品国产免费| 91蝌蚪porny九色| 男人的j进女人的j一区| 成人免费在线播放视频| 亚洲精品一区二区三区精华液| 成人黄色一级视频| 国产91在线|亚洲| 久久国产婷婷国产香蕉| 亚洲最大的成人av| 亚洲欧美在线另类| 亚洲少妇30p| 5858s免费视频成人| 一区二区三区四区精品在线视频| 国产成人一区在线| 国产一区二区三区最好精华液| 亚洲欧美日韩人成在线播放| 亚洲电影一级黄| 欧美精品一区二区三区在线| 日本女优在线视频一区二区| 国产日韩精品一区二区三区| 六月丁香综合在线视频| 日韩欧美中文字幕公布| 午夜精品久久久久影视| 777欧美精品| 亚洲人成网站色在线观看| 亚洲不卡一区二区三区| 亚洲电影在线播放| 91麻豆精品91久久久久久清纯| 久久久久久久网| 国产午夜精品久久久久久久| 亚洲欧洲成人自拍| 亚洲国产精品欧美一二99| 国产真实乱偷精品视频免| 美女视频黄 久久| av毛片久久久久**hd| 91亚洲精品乱码久久久久久蜜桃| 色香蕉久久蜜桃| 精品毛片乱码1区2区3区 | 日韩美女视频在线| 日韩欧美一级精品久久| 国产成人午夜精品影院观看视频| 中文字幕在线一区二区三区| 91美女福利视频| 蜜桃久久精品一区二区| 国产精品久久久久久户外露出| 欧美日韩国产美女| **网站欧美大片在线观看| 日韩av在线发布| 国产精品 欧美精品| 欧美v亚洲v综合ⅴ国产v| 久久久久国产精品人| 成人免费三级在线| 日韩一级黄色片| 顶级嫩模精品视频在线看| 97se亚洲国产综合自在线| 91精品91久久久中77777| 亚洲bt欧美bt精品| 欧美激情一二三区| 免费精品视频在线| 亚洲午夜久久久久久久久电影院| 99久久综合99久久综合网站| 日韩一区二区三区免费看| 石原莉奈在线亚洲二区| 精品欧美黑人一区二区三区| 亚洲chinese男男1069| 日韩亚洲欧美综合| eeuss鲁一区二区三区| 国产精品久久久久久亚洲伦| 在线看日韩精品电影| 色综合天天天天做夜夜夜夜做|