Go语言 大话数据结构——二叉树(字符类型数据)

二叉树是树的特殊一种,具有如下特点:1、每个结点最多有两颗子树,结点的度最大为2。2、左子树和右子树是有顺序的,次序不能颠倒。3、即使某结点只有一个子树,也要区分左右子树。

一、特殊的二叉树及特点

 

1、斜树

所有的结点都只有左子树(左斜树),或者只有右子树(右斜树)。这就是斜树,应用较少

Go语言 大话数据结构——二叉树(字符类型数据)_第1张图片Go语言 大话数据结构——二叉树(字符类型数据)_第2张图片

2、满二叉树

所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上,这样就是满二叉树。就是完美圆满的意思,关键在于树的平衡。

Go语言 大话数据结构——二叉树(字符类型数据)_第3张图片

根据满二叉树的定义,得到其特点为:

  1. 叶子只能出现在最下一层。
  2. 非叶子结点度一定是2.
  3. 在同样深度的二叉树中,满二叉树的结点个数最多,叶子树最多。

3、完全二叉树

对一棵具有n个结点的二叉树按层序排号,如果编号为i的结点与同样深度的满二叉树编号为i结点在二叉树中位置完全相同,就是完全二叉树。满二叉树必须是完全二叉树,反过来不一定成立。

其中关键点是按层序编号,然后对应查找。

Go语言 大话数据结构——二叉树(字符类型数据)_第4张图片

 

在上图中,树1,按层次编号5结点没有左子树,有右子树,10结点缺失。树2由于3结点没有字数,是的6,7位置空挡了。树3中结点5没有子树。

Go语言 大话数据结构——二叉树(字符类型数据)_第5张图片

上图就是一个完全二叉树。

结合完全二叉树定义得到其特点:

  1. 叶子结点只能出现在最下一层(满二叉树继承而来)
  2. 最下层叶子结点一定集中在左 部连续位置。
  3. 倒数第二层,如有叶子节点,一定出现在右部连续位置。
  4. 同样结点树的二叉树,完全二叉树的深度最小(满二叉树也是对的)。

二叉树遍历

二叉树遍历:从树的根节点出发,按照某种次序依次访问二叉树中所有的结点,使得每个结点被访问仅且一次。

这里有两个关键词:访问次序。

1、前序遍历

基本思想:先访问根结点,再先序遍历左子树,最后再先序遍历右子树即根—左—右

图中前序遍历结果是:1,2,4,5,7,8,3,6。

2、中序遍历

基本思想:先中序遍历左子树,然后再访问根结点,最后再中序遍历右子树即左—根—右。

图中中序遍历结果是:4,2,7,8,5,1,3,6。

3、后序遍历

 

基本思想:先后序遍历左子树,然后再后序遍历右子树,最后再访问根结点即左—右—根。

图中后序遍历结果是:4,8,7,5,2,6,3,1。

实例代码:

package main

import "fmt"

type TElemType string //树的数据类型
type BiTNode struct {
	data   TElemType
	Lchild *BiTNode
	Rchild *BiTNode //分别定义左子树 右子树
	count  int
}
type BitTree *BiTNode

/*
  fun:创建树  通过递归,以前序方式进行数据的添加
*/
func createBiTree() (*BiTNode) {
	var ch TElemType
	fmt.Println("请输入添加的数据:")
	fmt.Scan(&ch)
	var T BitTree

	if ch == "#" { //以#作为结束符
		T = nil
	} else {
		T = BitTree(new(BiTNode)) //分配内存空间
		(*T).data = ch
		(*T).Lchild = createBiTree() //创建左子树
		(*T).Rchild = createBiTree() //创建右子树
	}
	return T
}

/*
	fun:前序遍历   如果为空,返回;先打印节点,在通过递归显示左子树,之后通过递归显示右子树
*/
func preOrderTraverse(T BitTree) {
	if T == nil {
		return
	}
	fmt.Println(T.data)
	preOrderTraverse(T.Lchild)
	preOrderTraverse(T.Rchild)
}

/*
	fun:中序遍历   如果为空,返回;先通过递归遍历左子树,显示节点,再遍历右子树
*/
func inOrederTraverse(T BitTree) {
	if T == nil {
		return
	}
	inOrederTraverse(T.Lchild)
	fmt.Println(T.data)
	inOrederTraverse(T.Rchild)

}

func postOrederTraverse(T BitTree) {
	if T == nil {
		return
	}
	postOrederTraverse(T.Lchild)
	postOrederTraverse(T.Rchild)
	fmt.Println(T.data)
}

/*
	fun:计算二叉树节点的数量
*/
func NodeNum(T BitTree) int {
	if T == nil {
		return 0
	} else {
		return (1 + NodeNum(T.Lchild) + NodeNum(T.Rchild)) //返回根节点(1)+左子树的数量+右子树的数量
	}
}

/*
		fun:计算二叉树的深度
*/
func DepthofTree(T BitTree) int {
	if T == nil {
		return 0
	} else {
		leftDepth := DepthofTree(T.Lchild)
		rightDepth := DepthofTree(T.Rchild)
		if leftDepth > rightDepth {
			return 1+leftDepth
		} else {
			return 1+rightDepth
		}
	}
}

/*
      fun:计算二叉树的叶子节点
*/
func LeafNum(T BitTree) int {
	if T == nil {
		return 0
	} else if T.Lchild == nil && T.Rchild == nil {
		return 1
	}else {
		return (LeafNum(T.Lchild)+LeafNum(T.Rchild))
	}
}
/*
	fun:二叉树的查找:  返回节点
*/
func findData(T BitTree,data TElemType) BitTree {
	if T==nil {
		return nil
	}
	if T.data==data {
		return T
	}else {
		t:=findData(T.Lchild,data)
		if t!=nil {
			return t

		}
		return findData(T.Rchild,data)
	}
	//return nil

}

func main() {
	//var t BitTree
	t := createBiTree()
	//fmt.Println(t.count,flag)
	fmt.Println("前序遍历:")
	preOrderTraverse(t)
	fmt.Println("中序遍历")
	inOrederTraverse(t)
	fmt.Println("后续遍历")
	postOrederTraverse(t)
	fmt.Println("二叉树的节点数量:")
	nodeCount:=NodeNum(t)
	fmt.Println(nodeCount)
	fmt.Println("二叉树的度为:")
	depth:=DepthofTree(t)
	fmt.Println(depth)
	fmt.Println("二叉树的叶子节点为:")
	leaf:=LeafNum(t)
	fmt.Println(leaf)
	fmt.Println("查找二叉树")
	dataNode:=findData(t,TElemType("B"))
	if dataNode==nil {
		fmt.Println("没有找到!")
	}else {
		fmt.Println(dataNode.data)
	}

}

运行效果:

输入数据:

Go语言 大话数据结构——二叉树(字符类型数据)_第6张图片

运行效果:

Go语言 大话数据结构——二叉树(字符类型数据)_第7张图片

Go语言 大话数据结构——二叉树(字符类型数据)_第8张图片

Go语言 大话数据结构——二叉树(字符类型数据)_第9张图片

你可能感兴趣的:(Go语言 大话数据结构——二叉树(字符类型数据))