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
发布了177 篇原创文章 · 获赞 116 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/HYZX_9987/article/details/104660223