解法一:中序遍历
go
// Definition for a Node.
type Node struct {
Val int
Left *Node
Right *Node
}
// treeToDoublyList 将二叉搜索树转换为循环双向链表
// 中序遍历BST得到有序节点,再调整指针形成双向循环链表
func treeToDoublyList(root *Node) *Node {
if root == nil {
return nil
}
var pre, head *Node // pre: 前驱节点, head: 链表头节点
inorder(root, &pre, &head) // 中序遍历构建双向链表
// 首尾相连形成循环链表
if head != nil && pre != nil {
head.Left = pre // 头节点的左指针指向尾节点
pre.Right = head // 尾节点的右指针指向头节点
}
return head
}
// inorder 中序遍历二叉树,将节点转换为双向链表
// pre: 指向前驱节点的指针的指针,用于修改前驱节点
// head: 指向链表头节点的指针的指针,仅在第一个节点时赋值
func inorder(node *Node, pre **Node, head **Node) {
if node == nil {
return
}
// 1. 递归遍历左子树
inorder(node.Left, pre, head)
// 2. 中序位置,处理当前节点
if *pre == nil {
// 首次访问节点(最左叶子节点),标记为链表头
*head = node
} else { // 建立双向连接
// 前驱节点的右指针指向当前节点
(*pre).Right = node
// 当前节点的左指针指向前驱节点
node.Left = *pre
}
// 更新前驱节点为当前节点
*pre = node
// 3. 递归遍历右子树
inorder(node.Right, pre, head)
}