アイデア:
1.ツリーが空の場合、ルールに違反していないため、trueを返します。
2.ルートノードと左側のサブツリーの右側のサブツリーの値を比較し、等しくない場合はfalseを返します。
3.プレオーダートラバーサルは再帰的に実装できます。つまり、左側のサブツリーが右側のサブツリーと比較され、それらは等しくなければなりません。
bool isUnivalTree(struct TreeNode* root){
//先序遍历
if(root == NULL)
return true;
//判断==并没有多大的用处,判断相反可快速结束递归。
if(root->left && root->val != root->left->val)//1.判断节点是否存在,2.判断值是否不相等。
return false;
if(root->right && root->val != root->right->val)
return false;
return isUnivalTree(root->left) && isUnivalTree(root->right);//左树 右树都得同时满足才可返回真
}
2つのツリー間の比較は、対応するノードが存在し、等しいかどうかを確認することです。
アイデア:1。両方のツリーが空の場合、trueを返します。
2. 2つのツリーの対応するノードが欠落している場合は、falseを返します
3.再帰、事前注文トラバーサルを実行できます。
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
//同时为空树,返回真
if(p == NULL && q == NULL)
return true;
//当只有其中一个为空时,返回假
if(p == NULL || q == NULL)
return false;
//递归
if(p->val != q->val)
return false;
//左树遍历完遍历右树,且对应的左右书必须完全相等
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
2つのツリーが等しいかどうかの比較に基づいて、マイナーな変更が行われました。
ここでは、ルートノードの下のルート左サブツリーとルート右サブツリーを比較するだけで済みます。
比較には注意が必要です。これは鏡面対称であるため、左ツリーの左サブツリーと右ツリーの右サブツリーが比較されます。
左側のツリーの右側のサブツリーは、右側のサブツリーの左側のサブツリーと比較されます。
同じツリーのコードを呼び出すだけです。
bool _isSameTree(struct TreeNode* p, struct TreeNode* q){
//同时为空树,返回真
if(p == NULL && q == NULL)
return true;
//当只有其中一个为空时,返回假
if(p == NULL || q == NULL)
return false;
//递归
if(p->val != q->val)
return false;
//左树遍历完遍历右树,且对应的左右书必须完全相等
return _isSameTree(p->left,q->right) && _isSameTree(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root){
//为空树
if(root == NULL)
return true;
//调用相同树的代码
return _isSameTree(root->left,root->right);
}
レビュー:プレオーダートラバーサル:ルート-左サブツリー-右サブツリー
要するに、それはまだ再帰的な分割統治の考えですが、この質問は少し異なります。
この質問では、データを格納するために配列スペースを申請する必要があります。静的配列の使用は、関数スタックフレームのために関数がスコープ外になると破棄され、戻り値がまったく存在しない可能性があります。また、staticによって変更された静的ローカル変数は複数回呼び出され、データカバレッジの問題が発生します。最適な解決策は、ヒープ上のスペースを開く、どのくらいのスペースを開くかです。
最初に二分木をトラバースして、二分木のノード数を取得できます。対応するコードとアイデアは、以前のブログで言及されています。
アイデア:1。プレオーダートラバーサルのアイデア
2.ノードの数を再帰的に見つけます。
2.アレイを動的に開きます。
int BTreeSize(struct TreeNode* root)
{
return root == NULL? 0:BTreeSize(root->left)+BTreeSize(root->right)+1;
}
void _preorder(struct TreeNode* root,int* a,int* pi)
{
if(root == NULL)
return ;
a[(*pi)++] = root->val;
_preorder(root->left,a,pi);
_preorder(root->right,a,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
//确定树的大小
*returnSize = BTreeSize(root);
int* a = (int*)malloc(sizeof(int)*(*returnSize));
int i =0;
_preorder(root,a,&i);
return a;
}
ポストオーダートラバーサル:左サブツリー-右サブツリー-ルート
このアイデアは、上記のプレオーダートラバーサルと一致しています
int BTreeSize(struct TreeNode* root)
{
return root == NULL? 0:BTreeSize(root->left)+BTreeSize(root->right)+1;
}
void _preorder(struct TreeNode* root,int* a,int* pi)
{
if(root == NULL)
return ;
_preorder(root->left,a,pi);
_preorder(root->right,a,pi);
a[(*pi)++] = root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize){
*returnSize = BTreeSize(root);
int* a = (int*)malloc(sizeof(int)*(*returnSize));
int i =0;
_preorder(root,a,&i);
return a;
}
int BTreeSize(struct TreeNode* root)
{
return root == NULL? 0:BTreeSize(root->left)+BTreeSize(root->right)+1;
}
void _preorder(struct TreeNode* root,int* a,int* pi)
{
if(root == NULL)
return ;
_preorder(root->left,a,pi);
a[(*pi)++] = root->val;
_preorder(root->right,a,pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
*returnSize = BTreeSize(root);
int* a = (int*)malloc(sizeof(int)*(*returnSize));
int i =0;
_preorder(root,a,&i);
return a;
}
本質的に、それはサブツリーを見つける問題です。大きなツリーの小さなツリーと与えられた小さなツリーの構造と値が完全に等しい場合、trueを返します。
関数コードを呼び出して2つの数値が同じかどうかを判断し、分割統治のアイデアを採用し、最初に左側のサブツリーを実行して検索し、次に右側のサブツリーを実行して検索することを検討してください。期間中に見つかった場合は、直接trueを返します。
主に分岐のアイデア。
bool _isSameTree(struct TreeNode* p, struct TreeNode* q){
//同时为空树,返回真
if(p == NULL && q == NULL)
return true;
//当只有其中一个为空时,返回假
if(p == NULL || q == NULL)
return false;
//递归
if(p->val != q->val)
return false;
//左树遍历完遍历右树,且对应的左右书必须完全相等
return _isSameTree(p->left,q->left) && _isSameTree(p->right,q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
if(root == NULL && subRoot == NULL)
return true;
if(root == NULL || subRoot == NULL)
return false;
//判断其是否为相同的树,找完左树找右树
return _isSameTree(root,subRoot) || isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}
アイデア:1)木を作り、再帰的に分割統治します。
2)パラメータを渡す場合は、ポインタの受け渡し、値による呼び出し、仮パラメータの受け渡しが必要ですが、仮パラメータの変更は実際のパラメータに影響を与えないため、再帰時にエラーが発生します。
3)順序付きトラバーサル、左サブツリー-ルート-右サブツリー
#include<stdio.h>
#include<stdlib.h>
typedef struct BTreeNode
{
char data;
struct BTreeNode* left;
struct BTreeNode* right;
}BTNode;
BTNode* CreatTree(char *a, int *pi)//这里必须传递指针 pi
{
//递归方式创建树,那么就必须传址调用,而不是传值调用。
//如果是‘#’就返回NULL,同时找数组下一位
if(a[*pi] == '#')
{
(*pi)++;
return NULL;
}
//创建树
BTNode* root = (BTNode*)malloc(sizeof(BTNode));
root->data = a[(*pi)++];
root->left = CreatTree(a, pi);
root->right = CreatTree(a, pi);
return root;
}
void InOrder(BTNode* root)
{
if(root == NULL)
return;
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);
}
int main()
{
char a[100];
scanf("%s",a);
//创建树
int i = 0;
BTNode* Tree = CreatTree(a,&i);
InOrder(Tree);
return 0;
}