单向链表翻转
单向链表说明
单向链表的反转是一个非常常见的链表类面试题,在 leetcode 的中,发现了有许多链表题目的解法,都是以反转链表为基础进行的。所以在这里记录一下单向链表的翻转。如下图所示:
单链表的反转,就如上图一样,而单链表的反转也有几种方式,今天我主要是想记录我用得最频繁的迭代的方式。
先来看下链表节点的定义:
// 定义节点结构体
type Node struct {
Data interface{} // 接口类型的数据data
Next *Node // 下一个节点
}
这就是最基础的一个链表节点,而反转链表的代码,其实非常的短,关键点就在于理解这几行代码究竟让链表产生了什么变化。
// 单向链表翻转
func (l *LinkList) ReverseList() {
current := l.Header
var pre *Node
for current != nil {
current, current.Next, pre = current.Next, pre, current
}
l.Header = pre
}
二叉树翻转
二叉树翻转实现效果如下图所示:
先来看下二叉树节点的定义:
type Node struct {
Key int
Left *Node
Right *Node
}
实现翻转的函数(基于 golang 递归方式实现):
// 递归方式实现二叉树翻转
func (n *Node) RevTree() {
n.Left, n.Right = n.Right, n.Left
if n.Left != nil {
n.Left.RevTree()
}
if n.Right != nil {
n.Right.RevTree()
}
}
完整示例代码:
package main
import (
"encoding/json"
"fmt"
)
type Node struct {
Key int
Left *Node
Right *Node
}
// 递归方式实现二叉树翻转
func (n *Node) RevTree() {
n.Left, n.Right = n.Right, n.Left
if n.Left != nil {
n.Left.RevTree()
}
if n.Right != nil {
n.Right.RevTree()
}
}
// 测试
func main() {
tree := Node{
Key: 4,
Left: &Node{
Key: 2,
Left: &Node{
Key: 1,
Left: nil,
Right: nil,
},
Right: &Node{
Key: 3,
Left: nil,
Right: nil,
},
},
Right: &Node{
Key: 7,
Left: &Node{
Key: 6,
Left: nil,
Right: nil,
},
Right: &Node{
Key: 9,
Left: nil,
Right: nil,
},
},
}
tree.RevTree()
out, _ := json.MarshalIndent(tree, "", " ")
fmt.Println(string(out))
}
这里为了看一棵比较简单的树的结构,可以用json包序列化打印出来看:json.MarshalIndent(tree, "", " ")。