題目:

輸入一棵二元查詢樹,將該二元查詢樹轉換成一個排序的雙向連結串列。
要求不能建立任何新的結點,只調整指標的指向。
      10
     /   \
    6  14
   / \    / \
 4  8 12 16
轉換成雙向連結串列  4=6=8=10=12=14=16

分析:

1.  遇到樹相關的問題,首先應該想到遞迴,遞迴地處理左右子樹,獲得左子樹的 tail,右子樹的 head,

     將 “左子樹的 tail = root = 右子樹的 head” 連起來就 OK!

     綜合起來,遞迴函式應該能夠計算出以當前節點為 root 展成 LinkedList 後的 head 和 tail

2.  需要特別注意對指標引數的處理

package main

import "fmt"

type BSTreeNode struct {
	Value int
	Left  *BSTreeNode
	Right *BSTreeNode
}

func TreeToLinkedList(root *BSTreeNode) *BSTreeNode {
	var head, tail *BSTreeNode
	helper(&head, &tail, root)
	return head
}

// 注意對指標的操作(取地址符的使用)
func helper(head, tail **BSTreeNode, root *BSTreeNode) {
	var lt, rh *BSTreeNode
	if root == nil {
		*head, *tail = nil, nil
		return
	}
	helper(head, &lt, root.Left)
	helper(&rh, tail, root.Right)
	if lt != nil {
		lt.Right = root
		root.Left = lt
	} else {
		*head = root
	}
	if rh != nil {
		root.Right = rh
		rh.Left = root
	} else {
		*tail = root
	}
}

func RunTest() {
	// create a BSTree
	left := &BSTreeNode{1, nil, nil}
	right := &BSTreeNode{3, nil, nil}
	root := &BSTreeNode{2, left, right}

	head := TreeToLinkedList(root)

	for p := head; p != nil; p = p.Right {
		fmt.Printf("%d ", p.Value)
	}
}

func main() {
	RunTest()
}