二叉树遍历及算法实现

  • 遍历定义

指按某条搜索路线遍访每个结点且不重复(又称周游)。

  • 遍历用途

它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础和核心。 

  • 遍历方法

牢记一种约定,对每个结点的查看都是“先左后右”

限定先左后右,树的遍历有三种实现方案:

     DLR                 LDR                LRD

()序遍历        ()序遍历        ()序遍历

 

DLR — 先序遍历,即先根再左再右

LDR — 中序遍历,即先左再根再右

LRD — 后序遍历,即先左再右再根

注:“先、中、后”的意思是指访问的结点D是先于子树出现还是后于子树出现。

从递归的角度看,这三种算法是完全相同的,或者说这三种遍历算法的访问路径是相同的,只是访问结点的时机不同。

package main

import (
    "fmt"
    "reflect"
)

type BinaryNode struct {
    Data   interface{} //数据
    lChild *BinaryNode //左子树
    rChild *BinaryNode //右子树
}

//创建二叉树
func (node *BinaryNode) Create() {
    node = new(BinaryNode)
}

//先序遍历
func (node *BinaryNode) PreOrder() {
    if node == nil {
        return
    }
    //DLR — 先序遍历,即先根再左再右
    fmt.Println(node.Data)

    //递归遍历左子树
    node.lChild.PreOrder()
    //递归遍历右子树
    node.rChild.PreOrder()

}

//中序遍历
func (node *BinaryNode) MidOrder() {
    if node == nil {
        return
    }

    //LDR — 中序遍历,即先左再根再右
    //递归遍历左子树
    node.lChild.MidOrder()
    //打印数据
    fmt.Println(node.Data)
    //递归遍历右子树
    node.rChild.MidOrder()

}

//后序遍历
func (node *BinaryNode) RearOrder() {
    if node == nil {
        return
    }

    //LRD — 后序遍历,即先左再右再根
    //递归遍历左子树
    node.lChild.RearOrder()
    //递归遍历右子树
    node.rChild.RearOrder()
    //打印数据
    fmt.Println(node.Data)
}

//二叉树高度 深度
func (node *BinaryNode) TreeHeight() int {
    if node == nil {
        return 0
    }
    //进入下一层遍历
    lh := node.lChild.TreeHeight()
    rh := node.rChild.TreeHeight()
    if lh > rh {
        lh++
        return lh
    } else {
        rh++
        return rh
    }

}

//二叉树叶子节点个数
//叶子节点是没有后继的节点
func (node *BinaryNode) LeafCount(num *int) {
    if node == nil {
        return
    }
    //判断没有后继的节点为叶子节点
    if node.lChild == nil && node.rChild == nil {
        (*num)++
    }
    node.lChild.LeafCount(num)
    node.rChild.LeafCount(num)
}

//二叉树数据查找
func (node *BinaryNode) Search(Data interface{}) {
    if node == nil {
        return
    }

    //== 不支持slice 和 map
    //reflect.DeepEqual()
    if reflect.TypeOf(node.Data) == reflect.TypeOf(Data) && node.Data == Data {
        fmt.Println("找到数据", node.Data)
        return
    }
    node.lChild.Search(Data)
    node.rChild.Search(Data)
}

//二叉树销毁
func (node *BinaryNode) Destroy() {
    if node == nil {
        return
    }

    node.lChild.Destroy()
    node.lChild = nil
    node.rChild.Destroy()
    node.rChild = nil
    node.Data = nil

}

//二叉树反转
//如果想反转二叉树 二叉树必须是一个满二叉树
func (node *BinaryNode) Reverse() {
    if node == nil {
        return
    }

    //交换节点  多重赋值
    node.lChild, node.rChild = node.rChild, node.lChild

    node.lChild.Reverse()
    node.rChild.Reverse()

}

//二叉树拷贝
func (node *BinaryNode) Copy() *BinaryNode {
    if node == nil {
        return nil
    }
    lChild:=node.lChild.Copy()
    rChild:=node.rChild.Copy()

    //创建写节点 拷贝数据
    newNode:=new(BinaryNode)
    newNode.Data=node.Data
    newNode.lChild=lChild
    newNode.rChild=rChild
    return newNode
}
原文地址:https://www.cnblogs.com/peteremperor/p/13990939.html