golang实现链表反转,迭代法、递归法

链表反转golang实现

leetcode链接
剑指offer

解法一:迭代(执行用时0s,内存消耗2.5MB(81.56%))

1、 直接贴代码,看完注释还不懂你打死我!!!

func reverseList(head *ListNode) *ListNode {
	//判断head是否为nil若为nil则直接返回
	if head == nil {
		return head
	}
	//使用head保存当前元素
	//使用next保存下一个需要反转的元素,初始的时候为nil
	//定义pre保存当前元素的前一个元素初始为nil因为head未反转时,前一个元素是nil
	next := new(ListNode)
	var pre *ListNode = nil

	//循环链表,直至head为nil,如果head为空,则说明反转完成,返回head即可
	//最终返回的pre则是最终结果
	for head != nil {
		//先保存next变量以免反转过后找不到了
		next = head.Next
		//反转。将会head.next置为前一个元素
		head.Next = pre
		//反转后head为next,即下一个需要反转的变量,但是pre怎么存了,下一个pre应该是上一次的head,及上一次反转的节点,所以先保存pre,再保存head
		pre = head
		head = next
	}

	return pre
}

2、 测试

package reverseList

import (
	"fmt"
	"testing"
)

func Test_test(t *testing.T) {
	node3 := ListNode{
		Next: nil,
		Val: 3,
	}
	node2 := ListNode{
		Next: &node3,
		Val:  2,
	}

	head := ListNode{
		Next: &node2,
		Val: 1,
	}
	cur := reverseList(&head)
	for cur != nil {
		fmt.Println(cur.Val)
		cur = cur.Next
	}
}

结果
``
3
2
1


## 解法二-递归
1. 代码如下

//递归法 内存消耗太大了
//基线条件和递归条件
//编写递归函数时,必须告诉它何时停止递归。正因为如此,每个递归函数都有其两部分:基线部分和递归条件。
//递归条件指的是函数调用自己,而基线条件则指的的函数不再调用自己,从而避免形成无线循环。
func reverseList(head *ListNode) *ListNode {
//1->2->3=>1<-2<-3
//重复的部分就是把箭头反向
//如果从前逆转则next节点会找不到,所以要从后逆转,每一次退出到上一层,继续逆转上一层
//第一次逆转:1->2<-3;第二次逆转1<-2<3完成

//先找到最后一个节点,即为反转后的head
var newHead *ListNode
//head==nil是为了考虑特殊情况,传入空链表
if head ==nil || head.Next == nil {
	return head
}

newHead = reverseList(head.Next)
//寻找到最后一个节点即返回,此时newhead为最后一个节点,head为最后一个节点的前一个节点
//逆转
head.Next.Next = head
//将head.Next置为nil,防止形成环
head.Next = nil
return newHead

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值