go 语言 链表
鏈表指的是存儲(chǔ)結(jié)構(gòu)是鏈?zhǔn)降摹V该恳粋€(gè)結(jié)點(diǎn)除了本身數(shù)據(jù)之外,還有一個(gè)指針指向了下一個(gè)結(jié)點(diǎn)的地址。就像火車車廂,車廂本身是數(shù)據(jù),車鉤鏈接著下一個(gè)車廂。
鏈表有單鏈表,雙鏈表,循環(huán)鏈表結(jié)構(gòu),本節(jié)只介紹最簡單的單鏈表
單鏈表定義:
type Student struct {
Name string? ? ? ? ? ? ?//字段,也就是本身的數(shù)據(jù),可以有多個(gè)字段
Next* Student? ? ? ? ? //指向自己的指針字段
}
例:
type Student struct {Age intName stringNext *People } //定義包含兩個(gè)字段一個(gè)指針字段的Student的數(shù)據(jù)類型,為了好理解先定義了一個(gè)指向另一個(gè)數(shù)據(jù)類型的指針 type People struct {Age intName string } func testList() {//手動(dòng)構(gòu)造兩個(gè)節(jié)點(diǎn)var s Student //定義Student類型的變量ss.Age = 100 //給變量賦值s.Name = "abc"/*s.Next = &People{Age:100,Name:"efg",}*/ //這個(gè)注釋跟下面三行內(nèi)容一樣的效果。就是給s.Next分配指向People類型的內(nèi)存地址,并初始化
s.Next = new(People)s.Next.Age = 1000s.Next.Name = "efg"fmt.Printf("list header:%#v\n", s)fmt.Printf("data:%#v\n", *(s.Next)) } //輸出結(jié)果 list header:main.Student{Age:100, Name:"abc", Next:(*main.People)(0xc0420023e0)} data:main.People{Age:1000, Name:"efg"}
上面構(gòu)造了兩個(gè)節(jié)點(diǎn),如下圖所示:
下面我們?cè)赑eople類型里再添加一個(gè)指針,指向Student類型
type Student struct{Age intName stringNext *People } type People struct {Age intName stringNext *Student //添加一個(gè)指向Student類型的指針 } func testList(){var s Student //第一個(gè)結(jié)點(diǎn)s.Age = 100s.Name = "abc"s.Next = new(People) //第二個(gè)結(jié)點(diǎn)// s.Next = &People{// Age:100,// Name:"efg",// }s.Next.Age = 1000s.Next.Name = "efg"s.Next.Next = new(Student) //第三個(gè)結(jié)點(diǎn)s.Next.Next.Age = 100s.Next.Next.Name = "xyz"fmt.Printf("list header:%#v\n", s) //打印第一個(gè)結(jié)點(diǎn)的信息fmt.Printf("data:%#v\n", *(s.Next)) //打印第二個(gè)結(jié)點(diǎn)信息fmt.Printf("data:%#v\n", *(s.Next.Next)) //打印第三個(gè)節(jié)點(diǎn)的信息fmt.Printf("data:%#v\n", s.Next.Next.Next) //打錢第三個(gè)節(jié)點(diǎn)指針的地址} //輸出結(jié)果: list header:main.Student{Age:100, Name:"abc", Next:(*main.People)(0xc0420443a0)} data:main.People{Age:1000, Name:"efg", Next:(*main.Student)(0xc0420443c0)} data:main.Student{Age:100, Name:"xyz", Next:(*main.People)(nil)} data:(*main.People)(nil)現(xiàn)在構(gòu)造了三個(gè)結(jié)點(diǎn),如下圖所示:
上面構(gòu)造節(jié)點(diǎn)的方法慢,且邏輯復(fù)雜,而且指針是指向了另一種數(shù)據(jù)結(jié)構(gòu)類型的,需要對(duì)它進(jìn)行抽象。也就是說需要利用模板來生成結(jié)點(diǎn)。而且生成一個(gè)指向自己的指針,來構(gòu)造鏈表。
上面的方法是手動(dòng)構(gòu)造了三個(gè)節(jié)點(diǎn)的鏈表,下面利用函數(shù)來動(dòng)態(tài)的生成結(jié)點(diǎn)。
type Teacher struct{ //定義鏈表的存儲(chǔ)結(jié)構(gòu)Name stringAge intNext *Teacher } func createInHeader(h *Teacher, name string, age int) (*Teacher) { //這個(gè)函數(shù)的主要作用是生成一個(gè)新的結(jié)點(diǎn),并且把頭部結(jié)點(diǎn)的指針的值賦值給新的結(jié)點(diǎn),并且返回這個(gè)這個(gè)結(jié)點(diǎn)的內(nèi)存地址,再把這個(gè)新的結(jié)點(diǎn)的內(nèi)存地址賦值給頭部結(jié)點(diǎn)p := &Teacher{} //相當(dāng)于 var p *Teacher p = &Teacher{},申明變量,并分配一個(gè)內(nèi)存地址p.Age = age //字段屬性賦值p.Name = namep.Next = h //把頭結(jié)點(diǎn)指針的值賦值給新結(jié)點(diǎn)return p //返回新節(jié)點(diǎn)的地址 } func printList(h *Teacher){for h != nil{fmt.Printf("Name:%v Age:%v\n",h.Name,h.Age)h = h.Next //后移一個(gè)節(jié)點(diǎn)} } func testCreateInHeader() {var header *Teacher //定義一個(gè)指針變量header = createInHeader(header, "a", 18) //header指向第一個(gè)生成的結(jié)點(diǎn)header = createInHeader(header, "b", 19) //header指向第二個(gè)生成的結(jié)點(diǎn)header = createInHeader(header, "c", 20) //header指向第三個(gè)生成的結(jié)點(diǎn)printList(header) } //輸出結(jié)果 Name:c Age:20 Name:b Age:19 Name:a Age:18上面動(dòng)態(tài)生成三個(gè)結(jié)點(diǎn),每次相當(dāng)于前插,就是header指針變量每次都指向最新生成的那個(gè)結(jié)點(diǎn)。上面構(gòu)造的三個(gè)節(jié)點(diǎn)的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)為:
?
?下面演示從最后插入:
type Teacher struct{Name stringAge intNext *Teacher } func printList(h *Teacher){for h != nil{fmt.Printf("Name:%v Age:%v\n",h.Name,h.Age)h = h.Next} } func createInTail(tail *Teacher, name string, age int) (*Teacher) { //生成新的結(jié)點(diǎn),并把新生成的節(jié)點(diǎn)的地址返回給尾指針變量。尾指針變量永遠(yuǎn)指向最后一個(gè)結(jié)點(diǎn)。p := &Teacher{}p.Age = agep.Name = nameif tail == nil { //如果一開始沒有節(jié)點(diǎn),則直接返回新生成的結(jié)點(diǎn)的地址給尾指針變量return p}tail.Next = p //假設(shè)已經(jīng)有了一個(gè)節(jié)點(diǎn),那么tail != nil,則一行表示把原尾結(jié)點(diǎn)的指針指向新生成的結(jié)點(diǎn)return p //返回新生成結(jié)點(diǎn)的地址 } func testCreateInTail() {var header *Teachervar tail *Teachertail = createInTail(tail, "a", 18)if header == nil {header = tail //生成第一個(gè)節(jié)點(diǎn)時(shí),header也指向了第一個(gè)節(jié)點(diǎn)}tail = createInTail(tail, "b", 19)//尾指針永遠(yuǎn)指向新生成的結(jié)點(diǎn)tail = createInTail(tail, "c", 20)printList(header) }//輸出結(jié)果是:
Name:a Age:18
Name:b Age:19
Name:c Age:20
上面構(gòu)造的節(jié)點(diǎn)的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)為:
?
轉(zhuǎn)載于:https://www.cnblogs.com/wanghaijun999/p/8136253.html
總結(jié)
- 上一篇: .NET Core容器化@Docker
- 下一篇: ionic3 动态设置tabs页面底部导