利用go語言判斷是否是完全二叉樹

一、什麼是完全二叉樹?

先看如下這一張圖:

這個一顆二叉樹,如何區分該樹是不是完全二叉樹呢?

  • 當一個節點存在右子節點但是不存在左子節點這顆樹視為非完全二叉樹
  • 當一個節點的左子節點存在但是右子節點不存在視為完全二叉樹
  • 如果沒有子節點,那也是要在左側開始到右側依次沒有子節點才視為完全二叉樹,就像上圖2中

而上面第一張圖這顆二叉樹很明顯是一顆非完全二叉樹,因為在第三層也就是在節點2它並沒有右子節點。在6和4節點中隔開瞭一個節點(2節點沒有右子節點),所以不是完全二叉樹

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

二、流程

這道題可以使用按層遍歷的方式來解決:

  • 首先準備一個隊列,按層遍歷使用隊列是最好的一種解決方法
  • 首先將頭節點加入到隊列裡面(如果頭節點為空,你可以認為它是一個非完全二叉樹也可以認為它是完全二叉樹)
  • 遍歷該隊列跳出遍歷的條件是直到這個隊列為空時
  • 這個時候需要準備一個Bool的變量,如果當一個節點的左子節點或者右子節點不存在時將其置成true
  • 當Bool變量為true並且剩餘節點的左或右子節點不為空該樹就是非完全二叉樹
  • 當一樹的左子節點不存在並且右子節點存在,該樹也是非完全二叉樹

三、代碼

1.樹節點

type TreeNode struct {
	val   string
	left  *TreeNode
	right *TreeNode
}

2.測試代碼

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("不是完全二叉樹")
	}
}

3.判斷樹是否為完全二叉樹代碼

// 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
}

4.代碼解讀

這段代碼裡面沒有多少好說的,就說下for裡面第一個if判斷叭

這裡看下上面流程中最後兩個條件,當滿足最後兩個條件的時候才可以判斷出來這顆樹是否是完全二叉樹.

同樣因為實現判斷是否是完全二叉樹是通過對樹的按層遍歷來處理的,因為對樹的按層遍歷通過隊列是可以間單的實現的。所以這裡使用到瞭隊列

至於這裡為什麼要單獨創建一個isSingleNode變量:

  • 因為當有一個節點左側節點或者是右側的節點沒有的時候,在這同一層後面如果還有不為空的節點時,那麼這顆樹便不是完全二叉樹,看下圖

在這顆樹的最後一層綠色塗鴨處是少一個節點的,所以我用瞭一個變量我標識當前節點(在上圖表示節點2)的子節點是不是少一個,如果少瞭當前節點(在上圖表示節點2)的下一個節點(在上圖表示節點3)的子節點(在上圖表示4和5)如果存在則不是完全二叉樹,所以這就是創建瞭一個isSingleNode變量的作用

5.運行結果

到此這篇關於利用go語言判斷是否是完全二叉樹的文章就介紹到這瞭,更多相關go 二叉樹內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: