一:鏈表介紹
鏈表是有序的列表,但在內存的分部較為特殊

二:單鏈表的舉例使用
package main
import (
"fmt"
)
type Students struct{
num int
name string
next *Students
}
//尾部添加
func InsertStudentNode1(head *Students, student *Students){
//設置從頭部開始遍歷
temp := head
for {
if temp.next == nil {
break
}
temp = temp.next
}
temp.next=student
}
//有序添加
func InsertStudentNode2(head *Students, student *Students){
temp := head
for {
if temp.next == nil {
break
}else if temp.next.num > student.num {//按照有小到大添加
break
}else if temp.next.num == student.num {
fmt.Println("節點已存在")
return
}
temp = temp.next
}
student.next = temp.next
temp.next = student
}
//顯示所有節點
func ShowStudentNode(head *Students){
//設置從頭部開始遍歷
show := head
//先判斷是否為空鏈表
if show.next == nil {
fmt.Println("鏈表為空")
return
}
for {
if show.next == nil {
break
}
fmt.Printf("學生編號:%v,姓名:%v\n", show.next.num, show.next.name)
show = show.next
}
}
//刪除節點
func DelStudentNode(head *Students, num int){
temp := head
if temp.next == nil {
fmt.Println("鏈表為空")
return
}
for {
if temp.next.num == num {
break
}else if temp.next == nil {
fmt.Println("節點不存在")
return
}
temp = temp.next
}
temp.next = temp.next.next
}
func main() {
//初始化一個頭結點
head := &Students{}
//添加新節點
student1 := &Students{
num : 1,
name : "james",
}
student2 := &Students{
num : 2,
name : "kobe",
}
student5 := &Students{
num : 5,
name : "jorden",
}
student3 := &Students{
num : 3,
name : "shark",
}
// 添加節點
InsertStudentNode1(head, student1)
InsertStudentNode1(head, student2)
InsertStudentNode1(head, student5)
InsertStudentNode2(head, student3)
//獲取
ShowStudentNode(head)
//刪除編號為5的學生
DelStudentNode(head, 1)
fmt.Println("刪除后----------------")
//獲取
ShowStudentNode(head)
} 結果 [ `go run chainTable.go` | done ]
學生編號:1,姓名:james
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:5,姓名:jorden
刪除后----------------
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:5,姓名:jorden
三:雙向鏈表
①:雙線鏈表的優點
①-1:單向鏈表的查找方向只能向后查找,而雙線鏈表可以向后也可以向前;
①-2:單向鏈表不能自我刪除,需要其他節點的協助,而雙線鏈表可以自我刪除(根據指向的前節點與指向的后節點)
②:舉例說明
package main
import (
"fmt"
)
type Students struct{
num int
name string
pre *Students
next *Students
}
//尾部添加
func InsertStudentNode1(head *Students, student *Students){
//設置從頭部開始遍歷
temp := head
for {
if temp.next == nil {
break
}
temp = temp.next
}
temp.next=student
student.pre = temp
}
//有序添加
func InsertStudentNode2(head *Students, student *Students){
temp := head
last := false
for {
if temp.next == nil {
last = true
break
}else if temp.next.num > student.num {//按照有小到大添加
break
}else if temp.next.num == student.num {
fmt.Println("節點已存在")
return
}
temp = temp.next
}
if last {
temp.next = student
student.pre = temp
}else{
student.next = temp.next
temp.next = student
student.next.pre = student
student.pre = temp
}
}
//顯示所有節點
func ShowStudentNode(head *Students){
//設置從頭部開始遍歷
show := head
//先判斷是否為空鏈表
if show.next == nil {
fmt.Println("鏈表為空")
return
}
for {
if show.next == nil {
fmt.Println("最后節點的前一個節點信息")
fmt.Printf("學生編號:%v,姓名:%v\n", show.pre.num, show.pre.name)
return
}
fmt.Printf("學生編號:%v,姓名:%v\n", show.next.num, show.next.name)
show = show.next
}
}
//刪除節點
func DelStudentNode(head *Students, num int){
temp := head
if temp.next == nil {
fmt.Println("鏈表為空")
return
}
//用於判斷是否為最后一個節點
last := false
for {
if temp.next.num == num {
//再判斷一下是否為最后一個節點
if temp.next.next == nil {
last = true
}
break
}else if temp.next == nil {
fmt.Println("節點不存在")
return
}
temp = temp.next
}
if last {
temp.next = nil
}else{
temp.next = temp.next.next
temp.next.pre = temp
}
}
func main() {
//初始化一個頭結點
head := &Students{}
//添加新節點
student1 := &Students{
num : 1,
name : "james",
}
student2 := &Students{
num : 2,
name : "kobe",
}
student5 := &Students{
num : 5,
name : "jorden",
}
student3 := &Students{
num : 3,
name : "shark",
}
// 添加節點
InsertStudentNode1(head, student1)
InsertStudentNode1(head, student2)
InsertStudentNode1(head, student5)
InsertStudentNode2(head, student3)
//獲取
ShowStudentNode(head)
//刪除編號為5的學生
DelStudentNode(head, 1)
fmt.Println("刪除后----------------")
//獲取
ShowStudentNode(head)
}
結果
[ `go run doubleChainTable.go` | done ]
學生編號:1,姓名:james
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:5,姓名:jorden
最后節點的前一個節點信息
學生編號:3,姓名:shark
刪除后----------------
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:5,姓名:jorden
最后節點的前一個節點信息
學生編號:3,姓名:shark
四:環形單向鏈表
①:介紹,參考環形數組隊列
②:環形單向鏈表與單向鏈表和雙向鏈表不同之處在於,head也要存放數據
③:使用舉例
package main
import (
"fmt"
)
type Students struct{
num int
name string
next *Students
}
//尾部添加
func InsertStudentNode1(head *Students, student *Students){
temp := head
//先判斷頭部是否為空
if temp.next == nil {
temp.num = student.num
temp.name = student.name
//自環
temp.next = temp
return
}
for {
if temp.next == head {
break
}
temp = temp.next
}
student.next = head
temp.next=student
}
//顯示所有節點
func ShowStudentNode(head *Students){
//設置從頭部開始遍歷
show := head
//先判斷是否為空鏈表
if show.next == nil {
fmt.Println("鏈表為空")
return
}
for {
fmt.Printf("學生編號:%v,姓名:%v\n", show.num, show.name)
if show.next == head {
break
}
show = show.next
}
}
//刪除節點
func DelStudentNode(head *Students, num int) *Students{
temp := head
helper := head//幫助節點跳過將要刪除的節點
if temp.next == nil {
fmt.Println("鏈表為空")
return head
}
//判斷是否只有一個節點
if temp.next == head {
if temp.num == num {
temp.next = nil
}else{
fmt.Println("節點不存着")
}
return head
}
//將helper定位到最后一個節點
for {
if helper.next == head{
break
}
helper = helper.next
}
//當節點有多個時
flag := true
for{
if temp.next == head{
break
}
if temp.num == num {
if temp == head{//判斷是否刪除頭節點
head = head.next
}
helper.next = temp.next
fmt.Println("num=",num)
flag = false
break
}
temp = temp.next
helper = helper.next
}
if flag {
if temp.num == num {
//說明要刪除的節點是最后一個,這時temp已經指向最后一個節點
helper.next = temp.next
}else{
fmt.Println("節點不存在")
}
}
//防止要刪除的節點是頭部,返回最新的頭部位置
return head
}
func main() {
//初始化一個頭結點
head := &Students{}
//添加新節點
student1 := &Students{
num : 1,
name : "james",
}
student2 := &Students{
num : 2,
name : "kobe",
}
student3 := &Students{
num : 3,
name : "shark",
}
student4 := &Students{
num : 4,
name : "shark",
}
// 添加節點
InsertStudentNode1(head, student1)
InsertStudentNode1(head, student2)
InsertStudentNode1(head, student3)
InsertStudentNode1(head, student4)
// 獲取
ShowStudentNode(head)
//刪除編號為5的學生
head = DelStudentNode(head, 1)
fmt.Println("刪除后----------------")
//獲取
ShowStudentNode(head)
}
結果
[ `go run circleChainTable.go` | done ]
學生編號:1,姓名:james
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:4,姓名:shark
num= 1
刪除后----------------
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:4,姓名:shark
