在面试的时候,经常会被问到各种和二叉树相关的问题,而和二叉树相关的问题,一般要和二叉树中的遍历方式结合起来。二叉树中最重要的几种遍历方式包括先序遍历、中序遍历、后序遍历和层序遍历。
其中先序遍历、中序遍历以及后序遍历可以有多种实现方式
分治算法和DFS搜索算法,都依赖于递归的程序结构。但二者有些许不同
分治算法实现
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return []int{}
}
left := preorderTraversal(root.Left)
right := preorderTraversal(root.Right)
res := append([]int{},root.Val)
res = append(res,left...)
res = append(res,right...)
return res
}
DFS算法实现
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return []int{}
}
var res []int
dfs(root,&res)
return res
}
func dfs(root *TreeNode,res *[]int){
if root == nil{
return
}
*res = append(*res,root.Val)
dfs(root.Left,res)
dfs(root.Right,res)
}
非递归实现
func preorderTraversal(root *TreeNode) []int {
if root == nil{
return []int{}
}
var preorder []int
cur := root
var stack []*TreeNode
for ;cur!=nil || len(stack)>0;{
fmt.Println(cur.Val,len(stack))
for ;cur!=nil;{
stack = append(stack,cur)
preorder = append(preorder,cur.Val)
cur = cur.Left
}
cur = stack[len(stack)-1]
stack = stack[:len(stack)-1]
}
return preorder
}
分治算法实现
func inorderTraversal(root *TreeNode) []int {
if root == nil{
return []int{}
}
left := inorderTraversal(root.Left)
right := inorderTraversal(root.Right)
var res []int
res = append(res,left...)
res = append(res,root.Val)
res = append(res,right...)
return res
}
DFS算法实现
func inorderTraversal(root *TreeNode) []int {
var res []int
dfs(root,&res)
return res
}
func dfs(root *TreeNode,res *[]int){
if root == nil{
return
}
dfs(root.Left,res)
*res = append(*res,root.Val)
dfs(root.Right,res)
}
非递归算法实现
func inorderTraversal(root *TreeNode) []int {
var res []int
var stack []*TreeNode
for cur:=root;cur!=nil||len(stack)>0;{
for ;cur!=nil;{
stack = append(stack,cur)
cur = cur.Left
}
cur = stack[len(stack)-1]
res = append(res,cur.Val)
stack = stack[:len(stack)-1]
cur = cur.Right
}
return res
}
分治算法实现
func postorderTraversal(root *TreeNode) []int {
if root == nil{
return []int{}
}
var res []int
left := postorderTraversal(root.Left)
right := postorderTraversal(root.Right)
res = append(res,left...)
res = append(res,right...)
res = append(res,root.Val)
return res
}
DFS算法实现
func postorderTraversal(root *TreeNode) []int {
var res []int
dfs(root,&res)
return res
}
func dfs(root *TreeNode,res *[]int){
if root == nil{
return
}
dfs(root.Left,res)
dfs(root.Right,res)
*res = append(*res,root.Val)
}
非递归实现
后序遍历非递归的实现,实际上用了一个比较取巧的方法,通过内容来实现
func postorderTraversal(root *TreeNode) []int {
var res []int
var stack []*TreeNode
for cur:=root;cur!=nil || len(stack)>0;{
for ;cur!=nil;{
stack = append(stack,cur)
res = append(res,cur.Val)
cur = cur.Right
}
cur = stack[len(stack)-1]
cur = cur.Left
stack = stack[:len(stack)-1]
}
reverse(res)
return res
}
func reverse(slice []int){
for l,r:=0,len(slice)-1;l<r;l,r=l+1,r-1{
slice[l],slice[r] = slice[r],slice[l]
}
}
使用一个队列
func levelOrder(root *TreeNode) [][]int {
var res [][]int
if root == nil{
return res
}
queue := []*TreeNode{root}
for ;len(queue) > 0;{
var curLevel []int
l := len(queue)
for i:=0;i<l;i++{
cur := queue[0]
curLevel = append(curLevel,queue[0].Val)
queue = queue[1:]
if cur.Left !=nil{
queue = append(queue,cur.Left)
}
if cur.Right != nil{
queue = append(queue,cur.Right)
}
}
res = append(res,curLevel)
}
return res
}
使用交替的数组
func levelOrder(root *TreeNode) [][]int {
if root == nil{
return [][]int{}
}
res := [][]int{}
curLevel := []*TreeNode{root}
for len(curLevel)!=0 {
nextLevel :=[]*TreeNode{}
//get cur level val and next level node
curLevelVal := []int{}
for _,node := range curLevel{
curLevelVal = append(curLevelVal,node.Val)
if node.Left!=nil {
nextLevel = append(nextLevel,node.Left)
}
if node.Right != nil{
nextLevel = append(nextLevel,node.Right)
}
}
res = append(res,curLevelVal)
curLevel = nextLevel
}
return res
}