时间:2022-07-27 11:17:14 | 栏目:Golang | 点击:次
先看如下这一张图:
这个一颗二叉树,如何区分该树是不是完全二叉树呢?
而上面第一张图这颗二叉树很明显是一颗非完全二叉树,因为在第三层也就是在节点2它并没有右子节点。在6和4节点中隔开了一个节点(2节点没有右子节点),所以不是完全二叉树
再看第二张图,这颗树就是一个完全二叉树,虽然在这个颗节点3没有右子节点,但是6 4 5节点之间并没有空缺的子节点,这里就解释了上面说的第三条(如何没有子节点,那也是在左侧开始到右侧依次没有子节点才视为完全二叉树)
这道题可以使用按层遍历的方式来解决:
type TreeNode struct { val string left *TreeNode right *TreeNode }
func main() { root := &TreeNode{val: "1"} root.left = &TreeNode{val: "2"} root.left.left = &TreeNode{val: "4"} root.left.right = &TreeNode{val: "10"} root.left.left.left = &TreeNode{val: "7"} root.right = &TreeNode{val: "3"} root.right.left = &TreeNode{val: "5"} root.right.right = &TreeNode{val: "6"} if IsCompleteBt(root) { fmt.Println("是完全二叉树") } else { fmt.Println("不是完全二叉树") } }
// IsCompleteBt 这里默认根节点为空属于完全二叉树,这个可以自已定义是否为完全二叉树/***/ func IsCompleteBt(root *TreeNode) bool { if root == nil { return true } /** * 条件: * 1.当一个节点存在右子节点但是不存在左子节点这颗树视为非完全二叉树 * 2.当一个节点的左子节点存在但是右子节点不存在视为完全二叉树 */ var tempNodeQueue []*TreeNode tempNodeQueue = append(tempNodeQueue, root) var tempNode *TreeNode isSingleNode := false for len(tempNodeQueue) != 0 { tempNode = tempNodeQueue[0] tempNodeQueue = tempNodeQueue[1:] if (isSingleNode && (tempNode.left != nil || tempNode.right != nil)) || (tempNode.left == nil && tempNode.right != nil){ return false } if tempNode.left != nil{ tempNodeQueue = append(tempNodeQueue,tempNode.left) }else{ isSingleNode = true } if tempNode.right != nil { tempNodeQueue = append(tempNodeQueue, tempNode.right) }else{ isSingleNode = true } } return true }
这段代码里面没有多少好说的,就说下for里面第一个if
判断叭
这里看下上面流程中最后两个条件,当满足最后两个条件的时候才可以判断出来这颗树是否是完全二叉树.
同样因为实现判断是否是完全二叉树是通过对树的按层遍历来处理的,因为对树的按层遍历通过队列是可以间单的实现的。所以这里使用到了队列
至于这里为什么要单独创建一个isSingleNode变量:
在这颗树的最后一层绿色涂鸭处是少一个节点的,所以我用了一个变量我标识当前节点(在上图表示节点2)的子节点是不是少一个,如果少了当前节点(在上图表示节点2)的下一个节点(在上图表示节点3)的子节点(在上图表示4和5)如果存在则不是完全二叉树,所以这就是创建了一个isSingleNode
变量的作用