中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

后序遍歷求解判斷一顆二叉樹是否為平衡二叉樹

發布時間:2020-07-14 21:16:17 來源:網絡 閱讀:593 作者:小止1995 欄目:編程語言

題目:輸入一棵二叉樹的根結點,判斷該樹是不是平衡二叉樹。如果某二叉樹中任意結點的左右子樹的深度相差不超過1,那么它就是一棵平衡二叉樹。


有了求二叉樹的深度的經驗之后再解決這個問題,我們很容易就能想到一個思路:在遍歷樹的每個結點的時候,調用函數TreeDepth得到它的左右子樹的深度。如果每個結點的左右子樹的深度相差都不超過1,按照定義它就是一棵平衡的二叉樹。這種思路對應的代碼如下:

bool IsBalanced(BinaryTreeNode* pRoot)
{
    if(pRoot == NULL)
        return true;
    int left = TreeDepth(pRoot->m_pLeft);
    int right = TreeDepth(pRoot->m_pRight);
    int diff = left - right;
    if(diff > 1 || diff < -1)
        return false;
    return IsBalanced(pRoot->m_pLeft) && IsBalanced(pRoot->m_pRight);
}


上面的代碼固然簡潔,但我們也要注意到由于一個節點會被重復遍歷多次,這種思路的時間效率不高。例如在函數IsBalance中輸入上圖中的二叉樹,首先判斷根結點(值為1的結點)的左右子樹是不是平衡結點。此時我們將往函數TreeDepth輸入左子樹根結點(值為2的結點),需要遍歷結點4、5、7。接下來判斷以值為2的結點為根結點的子樹是不是平衡樹的時候,仍然會遍歷結點4、5、7。毫無疑問,重復遍歷同一個結點會影響性能。接下來我們尋找不需要重復遍歷的算法。

如果我們用后序遍歷的方式遍歷二叉樹的每一個結點,在遍歷到一個結點之前我們已經遍歷了它的左右子樹。只要在遍歷每個結點的時候記錄它的深度(某一結點的深度等于它到葉節點的路徑的長度),我們就可以一邊遍歷一邊判斷每個結點是不是平衡的。

#include<iostream>
#include<stack>
using namespace std;
struct BinaryTreeNode
{
	int data;
	BinaryTreeNode* left;
	BinaryTreeNode* right;
	BinaryTreeNode(int x)
		:data(x)
		, left(NULL)
		, right(NULL)
	{}
};
class BinaryTree
{
protected:
	BinaryTreeNode* _root;
	BinaryTreeNode* _CreateBinaryTree(int* arr, int& index, int size)
	{
		BinaryTreeNode* root = NULL;
		if (index < size&&arr[index] != '#')
		{
			root = new BinaryTreeNode(arr[index]);
			root->left = _CreateBinaryTree(arr, ++index, size);
			root->right = _CreateBinaryTree(arr, ++index, size);
		}
		return root;
	}
	
public:
	BinaryTree()
		:_root(NULL)
	{}
	BinaryTree(int *arr, int size)
	{
		int index = 0;
		_root = _CreateBinaryTree(arr, index, size);
	}
	bool IsBalance()
	{
		int depth = 0;
		return _IsBalance(_root, depth);
	}
	int Height()
	{
		return _Height(_root);
	}
	void PreOrder_Non()
	{
		if (_root == NULL)
			return;
		BinaryTreeNode* cur = _root;
		stack<BinaryTreeNode*> s;
		s.push(_root);
		while (!s.empty())
		{
			cur = s.top();
			printf("%d ", cur->data);
			s.pop();
			if (cur->right)
				s.push(cur->right);
			if (cur->left)
				s.push(cur->left);
		}
		cout << endl;
	}
protected:
	int _Height(BinaryTreeNode* root)
	{
		if (root == NULL)
			return 0;
		int left = _Height(root->left);
		int right = _Height(root->right);
		return left > right ? left + 1 : right + 1;
	}
	bool _IsBalance(BinaryTreeNode* root, int& depth)
	{
		if (root == NULL)
			return true;
		int left, right;
		if (_IsBalance(root->left, left) && _IsBalance(root->right, right))
		{
			int dif = left - right;
			if (dif <= 1 && dif >= -1)
			{
				depth = left > right ? left + 1 : right + 1;
				return true;
			}
		}
		return false;
	}
};
int main()
{
	int a[] = { 1,2,3,'#','#','#'};
	BinaryTree t(a,sizeof(a)/sizeof(a[0]));
	
	t.PreOrder_Non();
	cout<<t.IsBalance()<<endl;
	
	system("pause");
	return 0;
}


在上面的代碼中,我們用后序遍歷的方式遍歷整棵二叉樹。在遍歷某結點的左右子結點之后,我們可以根據它的左右子結點的深度判斷它是不是平衡的,并得到當前結點的深度。當最后遍歷到樹的根結點的時候,也就判斷了整棵二叉樹是不是平衡二叉樹了。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

屯留县| 龙川县| 鄂州市| 巴彦县| 宝山区| 嘉祥县| 那曲县| 龙川县| 淮南市| 鄂尔多斯市| 河西区| 涞源县| 墨竹工卡县| 澄迈县| 西昌市| 讷河市| 汕尾市| 达尔| 诏安县| 疏勒县| 安图县| 黑水县| 新竹县| 泊头市| 开化县| 驻马店市| 弥渡县| 正镶白旗| 成安县| 广丰县| 浠水县| 灵璧县| 仙游县| 遵化市| 翼城县| 禄劝| 汕尾市| 泰兴市| 阿图什市| 建水县| 金溪县|