首页 > 编程语言 >二叉树相关算法题汇总-go语言实现

二叉树相关算法题汇总-go语言实现

时间:2024-06-10 21:21:33浏览次数:24  
标签:RightChild BNode int Data 汇总 LeftChild 二叉树 go root

总结

  • 先序 中序 后序 遍历就能解决一些算法题。
  • 层次遍历 使用队列。
  • 从左子树 、右子树 获取答案,然后结合根节点来 计算答案。
  • 前缀树,比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))
}

标签:RightChild,BNode,int,Data,汇总,LeftChild,二叉树,go,root
From: https://www.cnblogs.com/clllll/p/18241049

相关文章

  • Zgo - csv_data.go
     packagemainimport("encoding/csv""log""os")typeRecordstruct{NamestringSurnamestringNumberstringLastAccessstring}varmyData=[]Record{}funcreadCSVFile(file......
  • golang sync.Once 保证某个动作仅执行一次的机制
     typeOncestruct{doneatomic.Uint32mMutex} 这段代码是Go语言标准库中sync包的一部分,定义了一个Once类型。Once类型用于确保某个函数只被执行一次。它包含一个done原子类型和一个Mutex互斥锁。  done表示动作是否已经执行过,它被放置在结构......
  • 二叉树的所有路径-力扣
    这道题目需要返回给定二叉树所有从根节点到叶子节点的路径,那么对二叉树进行深度优先搜索,遇到节点就将其加到路径中,如果这个节点的左右子节点都为空,那么它就是一个叶子节点,将这条路径加入到结果数组中。这里将int转换为string使用了to_string()函数。/***Definition......
  • The Dragon Boat Festival
    TheDragonBoatFestival,alsoknownastheDuanwuFestival,isasignificantculturaleventinChina.Itfallsonthefifthdayofthefifthlunarmonth,atimewhenfamiliesgathertocelebrateandcommemoratetheancientpoetQuYuan.Thefestivalism......
  • 周报 | 24.6.3-24.6.9文章汇总
    为了更好地整理文章和发表接下来的文章,以后每周都汇总一份周报。OpenCV与AI深度学习|实战|OpenCV实现扫描文本矫正应用与实现详解(附源码)-CSDN博客DeepDriving|多目标跟踪算法之DeepSORT-CSDN博客GiantPandaCV|提升分类模型acc(一):BatchSize&LARS-CSDN博客天才程......
  • Zgo - randInt, randString
     packagemainimport("fmt""math/rand""strings")const(//AsweonlywanttogetprintableASCIIcharacters,welimittherangeofpseudo-randomnumbers//thatcanbegenerated.Thetotalnumber......
  • 【数据结构】前缀树(字典树)汇总
    基础{“a”,“abc”,“bac”,“bbc”,“ca”}的字典树如下图:最主用的应用:一,字符串编码。二,位运算。字符串编码相比利用哈希映射编码,优点如下:依次查询长度为n的字符串s的前缀时间复杂度是O(n)。查询完s[0…i],再查询s[0…i+1]的时间复杂度是O(1)。而哈希映射的时间复杂......
  • 分布式ID:SnowFlake 雪花算法 Go实现
    分布式ID特性:趋势有序性(作为数据库主键时,顺序IO相较随机IO更友好)较UUID更短(占用更小的存储,只占64bit)其它(略)64bit构成:时间偏移(42bit) |数据中心ID(5bit)|节点ID(5bit)|序号(12bit)可按需自定义调整某部分的bit长度,比如把节点ID改为3bit 时间偏移:当前时间-初......
  • 【四种语言一网打尽(C\C++\Python\Golang)】L1-006 连续因子
    L1-006连续因子一个正整数N的因子中可能存在若干连续的数字。例如630可以分解为3×5×6×7,其中5、6、7就是3个连续的数字。给定任一正整数N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。输入格式:输入在一行中给出一个正整数N(1<N<2^31)。输......
  • Zgo - custom_log.go
     packagemainimport("fmt""io""log""os""path")funcmain(){flag:=os.O_APPEND|os.O_CREATE|os.O_WRONLYlogFile:=path.Join(os.TempDir(),"mGo.log")......