直击面试之二叉树

本文详细介绍了如何使用Go语言实现二叉树的数据结构,包括节点创建、添加子树、查找公共父节点及各种遍历方式。通过具体代码示例,深入解析了二叉树的构建与操作过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试过程中经常会问到二叉树相关的问题,下面使用Go整理下二叉树相关问题的代码实现

树的定义

//define the data struct
type BinaryTree struct {
	pLeft  *BinaryTree	//The Left Branch
	pRight *BinaryTree	//The Right Branch
	value interface{}	//Store The Value Of Tree Node
}

树节点的创建以及添加左右子树节点

//create the BinaryTree node
func NewBinaryTree(value interface{}) *BinaryTree {
	return &BinaryTree{nil, nil, value}
}

//Add left BinaryTree node
func (pSelf *BinaryTree) AddLeft(pBinaryTree *BinaryTree) {
	pSelf.pLeft = pBinaryTree
}

//Add right BinaryTree node
func (pSelf *BinaryTree) AddRight(pBinaryTree *BinaryTree) {
	pSelf.pRight = pBinaryTree
}

//Get Left Node
func (pSelf *BinaryTree) GetLeft() *BinaryTree{
	return pSelf.pLeft
}

//Get Right Node
func (pSelf *BinaryTree) GetRight() *BinaryTree{
	return pSelf.pRight
}

查找N个节点的公共父节点

对于这类问题可以借助一个int变量标记一个节点的子树为目标节点的数量,当数量达标时将节点加入结果集中即可

//find common parent node
func FindCommonParant(pRoot *BinaryTree, pNodes []*BinaryTree) (int, []*BinaryTree) {
	if nil == pRoot || len(pNodes) <= 0 {
		return 0, nil
	}

	iLeftRet, leftnodes := FindCommonParant(pRoot.pLeft, pNodes)
	iRightRet, rightnodes := FindCommonParant(pRoot.pRight, pNodes)

	var result []*BinaryTree
	iFlag := iLeftRet + iRightRet
	if len(pNodes) == iFlag {
		result = append(result, leftnodes...)
		result = append(result, rightnodes...)
		result = append(result, pRoot)
	} else {
		for i := 0; i < len(pNodes); i++ {
			if pRoot == pNodes[i] {
				iFlag++ //current node as the target node
				break
			}
		}
	}

	return iFlag, result[:]
}

二叉树的遍历

二叉树节点为ANY类型,需实现打印接口

//二叉树节点实现接口
type Bter interface {
	Print() //节点的打印
}
//PreOrder traversal binary tree
func PreTraversal(pRoot *BinaryTree) {
	if nil != pRoot {
		if v, ok := pRoot.Value.(Bter); ok {
			v.Print()
		}

		PreTraversal(pRoot.pLeft)
		PreTraversal(pRoot.pRight)
	}
}

//非递归先序遍历
func PreTraversal1(pRoot *BinaryTree) {
	stack := make([]*BinaryTree, 0)
	for nil != pRoot {
		if nil != pRoot {
			//访问根节点
			if v, ok := pRoot.Value.(Bter); ok {
				v.Print()
			}

			//右节点先入栈
			if nil != pRoot.pRight {
				stack = append(stack, pRoot.pRight)
			}

			//访问左节点
			pRoot = pRoot.pLeft
		}

		//左节点访问完  右节点出栈
		if nil == pRoot && len(stack) > 0 {
			pRoot = stack[len(stack)-1]
			stack = stack[:len(stack)-1]
		}
	}
}

//Middle order traversal binary tree
func MidTraversal(pRoot *BinaryTree) {
	if nil != pRoot {
		MidTraversal(pRoot.pLeft)
		if v, ok := pRoot.Value.(Bter); ok {
			v.Print()
		}
		MidTraversal(pRoot.pRight)
	}
}

//非递归中序遍历
func MidTraversal1(pRoot *BinaryTree) {
	stack := make([]*BinaryTree, 0)
	for nil != pRoot {
		//根节点入栈
		stack = append(stack, pRoot)
		pRoot = pRoot.pLeft//先访问左节点
		for nil == pRoot && len(stack) > 0 {
			pRoot = stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			if v, ok := pRoot.Value.(Bter); ok {
				v.Print()
			}

			pRoot = pRoot.pRight
		}
	}
}

//Post order traversal binary tree
func PostTraversal(pRoot *BinaryTree) {
	if nil != pRoot {
		PostTraversal(pRoot.pLeft)
		PostTraversal(pRoot.pRight)
		if v, ok := pRoot.Value.(Bter); ok {
			v.Print()
		}
	}
}

//非递归后序遍历
func PostTraversal1(pRoot *BinaryTree) {
	stack := make([]*BinaryTree, 0)
	//后序遍历需要访问父节点的左右孩子节点  需要辅助HASH标记是否访问过
	m := make(map[*BinaryTree]struct{})
	for nil != pRoot {
		stack = append(stack, pRoot)
		pRoot = pRoot.pLeft
		for nil == pRoot && len(stack) > 0 {
			pRoot = stack[len(stack)-1]
			if _, ok := m[pRoot]; !ok {
				m[pRoot] = struct{}{}
				pRoot = pRoot.pRight
			} else {
				stack = stack[:len(stack)-1]
				if v, ok := pRoot.Value.(Bter); ok {
					v.Print()
				}

				pRoot = nil
			}
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值