判斷是否徹底二叉樹

Hello:git

​ 今天又和小夥伴們見面啦,最近一直作二叉樹相關的題目今天再和你們分享一道相關的題目《判斷是否是徹底二叉樹》github

判斷是不是徹底二叉樹

查看所有源碼:點擊查看所有源碼markdown

介紹-什麼是徹底二叉樹?

先看以下這一張圖:app

這個一顆二叉樹,如何區分該樹是否是徹底二叉樹呢?oop

  • 當一個節點存在右子節點可是不存在左子節點這顆樹視爲非徹底二叉樹
  • 當一個節點的左子節點存在可是右子節點不存在視爲徹底二叉樹
  • 若是沒有子節點,那也是要在左側開始到右側依次沒有子節點才視爲徹底二叉樹,就像上圖2中

而上面第一張圖這顆二叉樹很明顯是一顆非徹底二叉樹,由於在第三層也就是在節點2它並無右子節點。在6和4節點中隔開了一個節點(2節點沒有右子節點),因此不是徹底二叉樹測試

再看第二張圖,這顆樹就是一個徹底二叉樹,雖然在這個顆節點3沒有右子節點,可是6 4 5節點之間並無空缺的子節點,這裏就解釋了上面說的第三條(如何沒有子節點,那也是在左側開始到右側依次沒有子節點才視爲徹底二叉樹)ui

流程

這道題能夠使用按層遍歷的方式來解決:url

  • 首先準備一個隊列,按層遍歷使用隊列是最好的一種解決方法
  • 首先將頭節點加入到隊列裏面(若是頭節點爲空,你能夠認爲它是一個非徹底二叉樹也能夠認爲它是徹底二叉樹)
  • 遍歷該隊列跳出遍歷的條件是直到這個隊列爲空時
  • 這個時候須要準備一個Bool的變量,若是當一個節點的左子節點或者右子節點不存在時將其置成true
  • 當Bool變量爲true而且剩餘節點的左或右子節點不爲空該樹就是非徹底二叉樹
  • 當一樹的左子節點不存在而且右子節點存在,該樹也是非徹底二叉樹

代碼

樹節點

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變量:

  • 由於當有一個節點左側節點或者是右側的節點沒有的時候,在這同一層後面若是還有不爲空的節點時,那麼這顆樹便不是徹底二叉樹,看下圖

image-20210707163759637

在這顆樹的最後一層綠色塗鴨處是少一個節點的,因此我用了一個變量我標識當前節點(在上圖表示節點2)的子節點是否是少一個,若是少了當前節點(在上圖表示節點2)的下一個節點(在上圖表示節點3)的子節點(在上圖表示4和5)若是存在則不是徹底二叉樹,因此這就是建立了一個isSingleNode變量的做用

運行結果

image-20210707150308392

相關文章
相關標籤/搜索