go實現反轉鏈表

單獨把這個提出來成一篇文章,只是爲了方便看~

雙向鏈表操作點擊此處哦

                             時間平復了一時的衝動,卻加深了挫敗感。
                                                                ——馬爾克斯  《百年孤獨》
         
 

目錄

定義及基本操作

反轉

main函數

控制檯

定義及基本操作

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

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章