clllll  

总结

  • 先序 中序 后序 遍历就能解决一些算法题。
  • 层次遍历 使用队列。
  • 从左子树 、右子树 获取答案,然后结合根节点来 计算答案。
  • 前缀树,比Hashset更稳定。O(1),只不过占内存。trie树。
  • 递归。递归,递归。 到叶子节点收集答案。然后移除路径。
package main

import (
	"fmt"
	"math"

	. "github.com/isdamir/gotype"
)

// 将有序数组放置到二叉树中
// 取数组的中间元素为根节点。递归完成左右部分。

func arrayToTree(arr []int, start int, end int) *BNode {
	var root *BNode
	if end >= start {
		// root = new(BNode)
		root = NewBNode()
		mid := (start + end + 1) / 2
		root.Data = arr[mid]
		root.LeftChild = arrayToTree(arr, start, mid-1)
		root.RightChild = arrayToTree(arr, mid+1, end)
	}

	return root
}

// 层次遍历二叉树
func PrintTreeLayer(root *BNode) {
	// 考虑为空

	if root == nil {
		return
	}
	// 根节点入队
	q := &SliceQueue{}
	q.EnQueue(root)
	for !q.IsEmpty() {
		cur_node := q.DeQueue().(*BNode)
		fmt.Print(cur_node.Data, " ")
		if cur_node.LeftChild != nil {
			q.EnQueue(cur_node.LeftChild)
		}
		if cur_node.RightChild != nil {
			q.EnQueue(cur_node.RightChild)
		}
	}
}

// 计算一颗二叉树的最大子树和 。 后序遍历就好
var maxSum = math.MinInt64

func FindMaxSubTree(root *BNode, maxRoot *BNode) int {
	if root == nil {
		return 0
	}

	lmax := FindMaxSubTree(root.LeftChild, maxRoot)
	rmax := FindMaxSubTree(root.RightChild, maxRoot)

	sum := lmax + rmax + root.Data.(int)
	if sum > maxSum {
		maxSum = sum
		maxRoot.Data = root.Data
	}
	return sum
}

// 把二叉树转换为双向链表
//  PHead 1 2 3 PEnd  - root 4  5 6 7
var PHead *BNode
var PEnd *BNode

func InOrderBSTree(root *BNode) {

	if root == nil {
		return
	}
	// 转换左子树
	InOrderBSTree(root.LeftChild)

	root.LeftChild = PEnd // 4 -> 3
	if PEnd == nil {
		PHead = root //
	} else {
		PEnd.RightChild = root // 3 -> 4
	}

	PEnd = root //更新PEND 为 4
	//转换右子树
	InOrderBSTree(root.RightChild)

}

// 判断一个数组是否是二元查找树 后序遍历的序列
/**
1 3 2 5 7 6 4

根节点一定是4 。然后找到第一个大于根节点的5.5之前都要 <4 .
递归 左右部分
*/

func IsAfterOrder(arr []int, start int, end int) bool {
	if arr == nil {
		return false
	}
	root := arr[end]
	var i, j int

	// 1 3 2 5 7 6 4
	// 0 1 2 3 4 5 6
	for i = start; i < end; i++ {
		if arr[i] > root {
			break
		}
	}
	for j = i; j < end; j++ {
		if arr[j] < root {
			return false
		}
	}
	// start = 0   end = 6
	// i = 3
	// j = 5

	lresult := true
	rresult := true
	// 看 1 3 2 是不是
	if i > start {
		lresult = IsAfterOrder(arr, start, i-1)
	}
	// 看 5 7 6 是不是
	if j < end {
		rresult = IsAfterOrder(arr, i, end)
	}

	return lresult && rresult

}

// 找出排序二叉树上任意俩个节点的最近共同父节点

/**
方法一: 路径比对法。 root->n1 root->n2

*/

func GetPathFromRoot(root *BNode, node *BNode, s *SliceStack) bool {
	if root == nil {
		return false
	}

	if root.Data.(int) == node.Data.(int) {
		s.Push(root)
		return true
	}

	if GetPathFromRoot(root.LeftChild, node, s) || GetPathFromRoot(root.RightChild, node, s) {
		s.Push(root)
		return true
	}

	return false
}

func FindParentNode(root, node1, node2 *BNode) *BNode {
	s1 := NewSliceStack()
	s2 := NewSliceStack()

	GetPathFromRoot(root, node1, s1)
	GetPathFromRoot(root, node2, s2)

	var parent *BNode
	for t1, t2 := s1.Pop().(*BNode), s2.Pop().(*BNode); t1 != nil && t2 != nil && t1.Data.(int) == t2.Data.(int); {
		parent = t1
		t1 = s1.Pop().(*BNode)
		t2 = s2.Pop().(*BNode)
	}

	return parent

}

// 后序遍历法

func FindParentNodeReverse(root, node1, node2 *BNode) *BNode {

	if root == nil || root.Data.(int) == node1.Data.(int) || root.Data.(int) == node2.Data.(int) {
		return root
	}

	l := FindParentNodeReverse(root.LeftChild, node1, node2)
	r := FindParentNodeReverse(root.RightChild, node1, node2)

	if l == nil {
		return r
	} else if r == nil {
		return l
	} else {
		return root
	}

}

// 复制二叉树

func DupTree(root *BNode) *BNode {
	if root == nil {
		return nil
	}

	dupTree := NewBNode()

	dupTree.Data = root.Data
	dupTree.LeftChild = DupTree(root.LeftChild)
	dupTree.RightChild = DupTree(root.RightChild)

	return dupTree

}

//找出与输入整数相等的所有路径

// 先序遍历,到了叶子节点收集答案。然后要清除自己的路径

func FindRoad(root *BNode, num, sum int, v []int) {
	sum += root.Data.(int)

	v = append(v, root.Data.(int))

	if root.LeftChild == nil && root.RightChild == nil && sum == num {
		for _, v := range v {
			fmt.Print(v, " ")
		}
	}

	if root.LeftChild != nil {
		FindRoad(root.LeftChild, num, sum, v)
	}

	if root.RightChild != nil {
		FindRoad(root.RightChild, num, sum, v)
	}

	sum -= v[len(v)-1]
	v = v[:len(v)-1]

}

// 反转二叉树 。递归

func ReverseTree(root *BNode) {
	if root == nil {
		return
	}

	ReverseTree(root.LeftChild)
	ReverseTree(root.RightChild)

	tmp := root.LeftChild
	root.LeftChild = root.RightChild
	root.RightChild = tmp
}

// 二叉树 路径最大的和
var trieNode *TrieNode

func main() {
	// 二叉数 B  B+
	// data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	// fmt.Println("arr:", data)
	// root := arrayToTree(data, 0, len(data)-1)
	// PrintTreeMidOrder(root)
	// fmt.Println()
	// fmt.Println("层序遍历")
	// PrintTreeLayer(root)
	//
	// root := &BNode{}
	// n1 := &BNode{}
	// n2 := &BNode{}
	// n3 := &BNode{}
	// n4 := &BNode{}

	// root.Data = 6
	// n1.Data = 3
	// n2.Data = -7
	// n3.Data = -1
	// n4.Data = 9

	// root.LeftChild = n1
	// root.RightChild = n2
	// n1.LeftChild = n3
	// n1.RightChild = n4
	// mr := &BNode{}
	// FindMaxSubTree(root, mr)
	// fmt.Println("max sub tree:", maxSum, mr.Data)

	// data := []int{1, 2, 3, 4, 5, 6, 7}
	// root := arrayToTree(data, 0, len(data)-1)
	// InOrderBSTree(root)
	// for cur := PHead; cur != nil; cur = cur.RightChild {
	// 	fmt.Print(cur.Data, " ")
	// }
	// data := []int{1, 3, 9, 2, 7, 6, 4}
	// r := IsAfterOrder(data, 0, len(data)-1)
	// if r {
	// 	fmt.Print("是后序遍历")
	// }
	// data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	// r := arrayToTree(data, 0, len(data)-1)
	// n1 := r.LeftChild.LeftChild.LeftChild
	// n2 := r.LeftChild.RightChild

	// res := FindParentNode(r, n1, n2)

	// if res != nil {
	// 	fmt.Println("parent:", n1.Data, n2.Data, res.Data)
	// }

	// res2 := FindParentNodeReverse(r, n1, n2)
	// if res2 != nil {
	// 	fmt.Println("parent:", n1.Data, n2.Data, res2.Data)
	// }

	// data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	// r := arrayToTree(data, 0, len(data)-1)
	// dr := DupTree(r)
	// PrintTreeMidOrder(r)
	// PrintTreeMidOrder(dr)

	r := NewBNode()
	n1 := NewBNode()
	n2 := NewBNode()
	n3 := NewBNode()
	n4 := NewBNode()

	r.Data = 6
	n1.Data = 3
	n2.Data = -7
	n3.Data = -1
	n4.Data = 9
	r.LeftChild = n1
	r.RightChild = n2
	n1.LeftChild = n3
	n1.RightChild = n4

	FindRoad(r, -1, 0, make([]int, 0))
}
posted on 2024-06-10 21:08  llcl  阅读(3)  评论(0编辑  收藏  举报