Hello:git
今天又和小夥伴們見面啦,最近一直作二叉樹相關的題目今天再和你們分享一道相關的題目《判斷是否是徹底二叉樹》github
查看所有源碼:點擊查看所有源碼markdown
先看以下這一張圖:app
![]() |
![]() |
---|
這個一顆二叉樹,如何區分該樹是否是徹底二叉樹呢?oop
而上面第一張圖這顆二叉樹很明顯是一顆非徹底二叉樹,由於在第三層也就是在節點2它並無右子節點。在6和4節點中隔開了一個節點(2節點沒有右子節點),因此不是徹底二叉樹測試
再看第二張圖,這顆樹就是一個徹底二叉樹,雖然在這個顆節點3沒有右子節點,可是6 4 5節點之間並無空缺的子節點,這裏就解釋了上面說的第三條(如何沒有子節點,那也是在左側開始到右側依次沒有子節點才視爲徹底二叉樹)ui
這道題能夠使用按層遍歷的方式來解決:url
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
判斷叭spa
這裏看下上面流程中最後兩個條件,當知足最後兩個條件的時候才能夠判斷出來這顆樹是不是徹底二叉樹.3d
一樣由於實現判斷是不是徹底二叉樹是經過對樹的按層遍從來處理的,由於對樹的按層遍歷經過隊列是能夠間單的實現的。因此這裏使用到了隊列
至於這裏爲何要單首創建一個isSingleNode
變量:
在這顆樹的最後一層綠色塗鴨處是少一個節點的,因此我用了一個變量我標識當前節點(在上圖表示節點2)的子節點是否是少一個,若是少了當前節點(在上圖表示節點2)的下一個節點(在上圖表示節點3)的子節點(在上圖表示4和5)若是存在則不是徹底二叉樹,因此這就是建立了一個isSingleNode
變量的做用