單獨把這個提出來成一篇文章,只是爲了方便看~
時間平復了一時的衝動,卻加深了挫敗感。
——馬爾克斯 《百年孤獨》
目錄
定義及基本操作
package main
import "fmt"
type ListNode struct {
Data int
Next *ListNode
}
type List struct {
First *ListNode
Last *ListNode
Size int
}
// 創建一個空的單鏈表
func CreateNewDanAirList() (list *List) {
return &List{}
}
// 給鏈表末尾新增一個節點
func (list *List) AddOneNodeToDan(value int) {
newNode := new(ListNode)
newNode.Data = value
// 鏈表爲空時
if list.Size < 1 {
list.First = newNode
list.Last = newNode
} else {
// 鏈表的長度>=1時
lastNode := list.Last
lastNode.Next = newNode
newNode.Next = nil
list.Last = newNode
}
list.Size += 1
}
// 刪除鏈表末尾節點
func (list *List) RemoveOneNode() {
// 鏈表爲空時
if list.Size < 1 {
return
} else {
// 鏈表的長度>=1時
lastCount := list.Size
last2Count := list.Size - 1
if lastCount == 1 {
list.First = nil
list.Last = nil
return
}
last2Node := &ListNode{}
currentNode := list.First
for i := 1; i <= lastCount; i++ {
if i >= 2 {
currentNode = currentNode.Next
if i == last2Count {
last2Node = currentNode
}
}
}
last2Node.Next = nil
list.Last = last2Node
}
list.Size -= 1
}
// 刪除鏈表首節點
func (list *List) RemoveOneNodeFront() {
if list.Size < 1 {
return
}
firstNode := list.First
list.First = firstNode.Next
list.Size -= 1
}
// 給鏈表開始新增一個節點
func (list *List) AddOneNodeToDan2Front(value int) {
newNode := new(ListNode)
newNode.Data = value
// 鏈表爲空時
if list.Size < 1 {
list.First = newNode
list.Last = newNode
} else {
// 鏈表的長度>=1時
firstNode := list.First
newNode.Next = firstNode
list.First = newNode
}
list.Size += 1
}
反轉
/*
思路:逆序添加,完成後刪除舊數據
如果你要問爲什麼還加協程,我也不知道爲什麼,喜歡協程,就當玩玩
*/
func (list *List) reverseList1(ch chan int) {
go func() {
currentNode := &ListNode{}
for i := 0; i < list.Size; i++ {
if i == 0 {
currentNode = list.First
ch <- currentNode.Data
currentNode = currentNode.Next
continue
}
if currentNode.Next == nil {
ch <- currentNode.Data
close(ch)
return
}
ch <- currentNode.Data
currentNode = currentNode.Next
}
}()
for value := range ch {
list.AddOneNodeToDan2Front(value)
}
for i := 0; i < list.Size; i++ {
list.RemoveOneNode()
}
}
/*
不斷插入更新前節點,讓Next形成倒序
*/
func (list *List) reverseList2() *ListNode {
currentNode := list.First
preNode, nextNode := new(ListNode), new(ListNode)
preNode, nextNode = nil, nil
// 勿使用:=&ListNode{}這種初始化,否則會出現data的零值形成多餘數據
for currentNode != nil {
nextNode = currentNode.Next
currentNode.Next = preNode // 當前節點指向前一個節點
preNode = currentNode // 前節點持續更新,循環結束時爲舊的最後一個數據
currentNode = nextNode
}
return preNode
}
/*
與第二種其實一樣,只是寫法更簡單
*/
func (list *List) reverseList3() *ListNode {
currentNode := list.First
var preNode *ListNode
for currentNode != nil { // node.Next爲nil時循環停止
currentNode.Next, preNode, currentNode = preNode, currentNode, currentNode.Next
}
return preNode
}
// 根據指定節點開始打印鏈表
func printNode(node *ListNode) {
for node != nil {
fmt.Print(node.Data, "\t")
node = node.Next
}
}
// 打印鏈表
func (list *List) printNode() {
node := list.First
for node != nil {
fmt.Println(node.Data)
node = node.Next
}
}
main函數
func main() {
// 測試
fmt.Println("--------------測試reverseList1---------------")
list0 := CreateNewDanAirList()
list0.AddOneNodeToDan(1)
list0.AddOneNodeToDan(2)
list0.AddOneNodeToDan(3)
list0.AddOneNodeToDan(4)
fmt.Println("先打印一下:")
printNode(list0.First)
fmt.Println("\n執行reverseList1反轉之後:")
ch := make(chan int)
list0.reverseList1(ch)
printNode(list0.First)
fmt.Println("\n--------------測試reverseList2---------------")
// 測試
list1 := CreateNewDanAirList()
list1.AddOneNodeToDan(7)
list1.AddOneNodeToDan(8)
list1.AddOneNodeToDan(9)
list1.AddOneNodeToDan(10)
fmt.Println("先打印一下:")
printNode(list1.First)
fmt.Println("\n執行reverseList2反轉之後:")
res1 := list1.reverseList2()
printNode(res1)
fmt.Println("\n--------------測試reverseList3---------------")
list2 := CreateNewDanAirList()
list2.AddOneNodeToDan(17)
list2.AddOneNodeToDan(18)
list2.AddOneNodeToDan(19)
list2.AddOneNodeToDan(20)
fmt.Println("先打印一下:")
printNode(list2.First)
fmt.Println("\n執行reverseList3反轉之後:")
res2 := list2.reverseList3()
printNode(res2)
}
控制檯
--------------測試reverseList1---------------
先打印一下:
1 2 3 4
執行reverseList1反轉之後:
4 3 2 1
--------------測試reverseList2---------------
先打印一下:
7 8 9 10
執行reverseList2反轉之後:
10 9 8 7
--------------測試reverseList3---------------
先打印一下:
17 18 19 20
執行reverseList3反轉之後:
20 19 18 17
Process finished with exit code 0