線性表包含兩種存儲方法:順序存儲結構和鏈式存儲結構,其中順序表的缺點是不便插入與刪除數據。
單鏈表:每個結點包含兩部分:數據域+指針域,上一個結點的指針指向下一結點,依次相連,形成鏈表。特別注意的是每個鏈表必須包含頭結點(數據域一般無意義或者為空,有時用來存儲鏈表長度等等)
下面的代碼實現鏈表的基本操作和輔助操作,基本操作指的是插入數據、刪除數據、查找數據、求鏈表長度;而輔助操作指的是創建結點、創建(初始化 )鏈表、判斷是否為空鏈表。和其他語言不同之處是Go語言具有垃圾自動回收的特性,因此不需要釋放指針或內存,后續沒有用到的變量Go語言會自動回收。
// 單鏈表:
package main
import "fmt"
// 創建節點結構/類型
type Node struct {
Data interface{}
Next *Node
}
// 創建鏈表結構
type LList struct {
Head *Node
Length int // 這里的鏈表長度不計入頭節點
}
// a.設計接口:
type Method interface {
Insert(i int, v interface{}) // 增
Delete(i int) // 刪
GetLength() int // 獲取長度
Search(v interface{}) int // 查
isNull() bool // 判斷是否為空
}
// b.初始化函數:
// 創建節點
func CreateNode(v interface{}) *Node {
return &Node{v, nil}
}
// 創建空鏈表
func CreateList() *LList {
return &LList{CreateNode(nil), 0}
}
// c.基於鏈表結構體實現接口 Method 中的方法:
// 在 i 處插入節點(前插??——即插入到原來的第 i 個節點之前,成為現在的第 i 個節點)
func (list *LList) Insert(i int, v interface{}) {
s := CreateNode(v)
pre := list.Head
for count:=0; count<=i; count++ {
if count == i-1 {
s.Next = pre.Next
pre.Next = s
list.Length++
}
pre = pre.Next
}
}
// 刪除第 i 處節點
func (list *LList) Delete(i int) {
pre := list.Head
for count:=0; count<=i-1; count++ {
s := pre.Next
if count == i-1 {
pre.Next = s.Next
list.Length--
}
pre = pre.Next
}
}
// 返回鏈表長度
func (list *LList) GetLength() int {
return list.Length
}
// 查詢值 v 所在的位置
func (list *LList)Search(v interface{}) int {
pre := list.Head.Next
for i:=1; i<=list.Length; i++ {
if pre.Data == v {
return i
}
pre = pre.Next
}
return 0
}
// 判空
func (list *LList) isNull() bool {
pre := list.Head.Next
if pre == nil {
return true
}
return false
}
// d.設計鏈表打印輸出函數:
func PrintList(list *LList) {
pre := list.Head.Next
fmt.Println("LList shows as follows: ...")
for i:=1; i<=list.Length;i++ {
fmt.Printf("%v\n", pre.Data)
pre = pre.Next
}
}
// main 函數:
func main() {
lList := CreateList()
fmt.Println("List is null: ", lList.isNull())
var M Method
M = lList // 接口類型的變量可以存儲所有實現該接口的類型變量
M.Insert(1, 3)
M.Insert(2, 6)
M.Insert(1, 5)
PrintList(lList)
fmt.Println("List length is: ", lList.Length)
fmt.Println("元素6在位置:", M.Search(6))
fmt.Println("元素100在位置:", M.Search(100))
fmt.Println("List is null: ", lList.isNull())
M.Delete(2)
PrintList(lList)
fmt.Println("List length is: ", lList.Length)
}
打印結果:
List is null: true
LList shows as follows: ...
5
3
6
List length is: 3
元素6在位置: 3
元素100在位置: 0
List is null: false
LList shows as follows: ...
5
6
List length is: 2