まず、バイナリツリーの概念
コンピュータサイエンスでは、バイナリツリーは、各ノードは、ツリー構造の最大で2つのサブツリーを持っています。通常、サブツリーが「左の部分木」(左部分木)と呼ばれ、「右部分木」(右部分木)され、バイナリツリーは、多くの場合、バイナリ検索ツリーとバイナリヒープを実装するために使用される。(Baiduの百科事典より抜粋)
1.完全なバイナリツリーは何ですか?
すべての子ノードのない最後のものを除いて、各レイヤー上のすべてのノードは、バイナリツリーの2つのつの子ノードを持っています。
2.完全なバイナリツリーは何ですか?
バイナリツリーは、ノードの底部のみ二つの層は、2以上であってもよく、最下部のリーフノードは、バイナリツリーが完全二分木と呼ばれるように、左のいくつかの場所で濃縮しました。
3、二分探索木は何ですか?
バイナリ検索ツリーは、二分探索木として知られています。xは、バイナリ検索ツリー内のノードとする、Xノードは、キーワードキーを含んで、xの主要ノードカウント値がキー、[X]です。yはxの左サブツリー内のノードが、鍵である場合、[Y] <=キー[X]; yはxの右サブツリー内のノードである場合、キー[Y]> =キー[X]
バイナリ検索ツリーで:
任意のノードは、その後、空でない左サブツリーの値をサブツリーを放置した場合(1)は、すべてのノードが少ないルートの値以下です。
(2)任意のノードの右サブツリーが空、右の部分木、根の値よりも大きいすべてのノードではありません。
左(3)任意のノードは、それぞれ右サブツリーは、バイナリ検索ツリーです。
(4)は、ノード鍵と等しくありません。
第二に、バイナリツリーの性質
プロパティ1:バイナリツリー内のノードの数まで、第i層2I-1(I> = 1 )
プロパティ2:最も2K-1ノードの深さkのバイナリツリー(K> = 1)
プロパティ3:少なくとも(log2n)を含むN個のノードのバイナリツリーの高さ+1
プロパティ4:ターミナルノードの数がN0場合いずれかのバイナリツリーで、次数2のノードの数がN0 = N2 + 1、n2と
第三に、一般的なバイナリインタフェース
- 構造が定義されています。
struct TreeNode
{
int val;
TreeNode *left;
TreeNode* right;
TreeNode(int x):val(x),left(NULL),right(NULL)
{}
};
- 以下是先序遍历递归与非递归接口
- 中序遍历的递归与非递归接口
- 后序遍历的递归与非递归接口
- 层次遍历二叉树
- 求二叉树的深度递归与非递归
- 判断一棵树是否为平衡二叉树
//先序遍历
//递归版本
void PreTraversal(vector<int> &v, TreeNode* root)
{
if (!root)
return;
v.push_back(root);
PreTraversal(v, root->left);
PreTraversal(v, root->right);
}
//非递归版本
void PreTraversal(vector<int> &v, TreeNode* root)
{
stack<TreeNode*> s;
s.push(root);
while (!s.empty())
{
TreeNode *cur = s.top();
s.pop();
if (temp)
{
v.push_back(cur->val);
s.push(root->right);
s.push(root->left);
}
}
}
//中序遍历 //左根右
void InorderTraversal(vector<int> &v, TreeNode* root)
{
if (!root) return;
InorderTraversal(v, root->left);
v.push(root->val);
InorderTraversal(v, root->right);
}
//非递归遍历
void InorderTraversal(vector<int> &v, TreeNode* root)
{
TreeNode* cur = root;
stack<TreeNode*> s;
while (root||!s.empty())
{
while (root)
{
s.push(root);
root = root->left;
}
TreeNode* cur = s.top();
s.pop();
v.push_back(cur->val);
root = cur->right;
}
}
//后序遍历
void PostorderTraversal(vector<int> &v, TreeNode* root)
{
if (!root) return;
PostorderTraversal(v, root->left);
PostorderTraversal(v, root->right);
v.push(root->val);
}
//非递归版本
void postOrderTraversal(vector<int> &store, TreeNode *root) {
stack<TreeNode *> S;
S.push(root);
while (!S.empty()) {
TreeNode *curr_node = S.top();
S.pop();
if (curr_node) {
store.push_back(curr_node->val);
S.push(curr_node->left); //右孩子优先,所以左孩子先入栈
S.push(curr_node->right);
}
}
std::reverse(store.begin(), store.end()); //逆序列即为所求
return;
}
//层次遍历
void LevelOrderTraversal(vector<int> &v, TreeNode *root)
{
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
TreeNode* ret = q->front();
q.pop();
if (ret)
{
v.push_back(ret->val);
q.push(ret->_left);
q.push(ret->right);
}
}
}
//二叉树的深度
int TreeDeepTh(TreeNode* root)
{
//递归法
return root ? 1 + max(TreeDeepth(root->left), TreeDeepth(root->right)):0;
}
//迭代法 用到层次遍历,层次就是我们的深度
int TreeDeepTh(TreeNode* root)
{
if (!root)
{
return 0;
}
int depth = 0;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int length = q.size();
++depth;
while (length--)
{
TreeNode* ret = q->front();
q.pop();
if (ret)
{
v.push_back(ret->val);
q.push(ret->_left);
q.push(ret->right);
length++;
}
}
}
return length;
}
//判断一棵树是否为平衡二叉树:平衡二叉树是指:它是一颗空树
//或者左右子树的高度差不超过1,并且左右子树都是一颗平衡二叉树
bool Isbalanced(TreeNode * root,int &Deepth)
{
if (!root)
{
Deepth = 0;
return true;
}
int left_depth, right_depth;
if (Isbalanced(root->left, left_depth) && Isbalanced(root->right, right_depth))
{
int diff = left_depth - right_depth;
if (diff <= 1 && diff >= -1)
{
Deepth = 1 + ((left_depth > right_depth) ? left_depth : right_depth);
return true;
}
}
return false;
}
bool IsBlancedTree(TreeNode* root)
{
int Deepth = 0;
return Isbalanced(root, Deepth);
}