目次
序文
バイナリ ツリーに関するいくつかの関連知識ポイントを以前に学習したので、今日はいくつかの演習を行います。以下に、バイナリ ツリーに関する leetcode の演習をいくつか紹介します。見てみましょう。
二分木関連リンク:
二分木の基本操作:データ構造-----二分木の基本操作-CSDNブログ
バイナリ ツリーの作成とトラバース:データ構造-----バイナリ ツリーの作成とトラバース - CSDN ブログ
二分木の基礎知識:データ構造-----ツリーと二分木の必須知識_Gretel Tadeのブログ-CSDNブログ
ヒープの関連メソッドのコード実装:データ構造-----ヒープ (完全なバイナリ ツリー) - CSDN ブログ
1. 二分木の順序通りの走査
バイナリ ツリーのルート ノードを指定すると
root
、 その 順序 トラバーサルを返します 。
アイデア分析:
この質問では、int 型のポインタ num が指定され、動的空間が配列として割り当てられ、次にバイナリ ツリー ノードの順序どおりの走査が実行され、取得されたデータが配列に格納され、最後に出力されることが必要です。この配列は、順序どおりの走査中に、保存するデータも取得されることを意味します。
コード:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
void travel(struct TreeNode* root, int*num,int*returnSize){
if(!root)
return;
travel(root->left,num,returnSize);
num[*returnSize]=root->val;
*returnSize+=1;
travel(root->right,num,returnSize);
}
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* inorderTraversal(struct TreeNode* root, int* returnSize){
int* num=(int*)malloc(sizeof(int)*100);
*returnSize=0;
if(!root)
return NULL;
travel(root,num,returnSize);
return num;
}
2. 同じ木
2 つのバイナリ ツリーのルート ノードの合計が与えられた場合
p
、q
2 つのツリーが同じかどうかをテストする関数を作成します。2 つのツリーは、構造的に同一であり、同じ値のノードを持つ場合、同一とみなされます。
アイデア分析:
同じ木であるかどうかを判定するには、同じ位置にノードが存在するかどうか、また、存在する場合にはその中の値が同じであるかどうかを判定する必要があり、以下の3つの状況が考えられます。1 つ目: どのノードも存在しない場合は true、2 つ目: 1 つのノードが存在し、もう 1 つのノードが存在しない場合は false、3 つ目: 内部の値が異なる場合、結果は false になります。上記の 3 つの状況では、左のサブツリーと右のサブツリーの走査と合計の操作を実行するだけです。
コード:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
if(!p&&!q)
return true;
if(!p||!q)
return false;
if(p->val!=q->val)
return false;
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
3. バイナリツリーの最大深さ
バイナリ ツリーを指定すると
root
、その最大の深さを返します。バイナリ ツリーの 最大の深さは 、ルート ノードから最も遠いリーフ ノードまでの最長パス上のノードの数です。
アイデア分析:
最大の深さを取得するには、つまり、毎回左と右のサブツリーを走査します。レイヤーが走査されるたびに、深さは 1 ずつ増加します。最終的にルート ノードに再帰するときに、左と右のサブツリーの現在の深さを比較します。このときは大きい方を選択し、1 回だけ返します。
コード:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int maxDepth(struct TreeNode* root){
if(!root){
return 0;
}
int l=maxDepth(root->left);
int r=maxDepth(root->right);
if(l>r)
return l+1;
else
return r+1;
}
4. 二分木の最小深さ
二分木が与えられた場合、その最小の深さを見つけます。
最小深さは、ルート ノードから最も近いリーフ ノードまでの最短パス上のノードの数です。
注:リーフ ノードとは、子ノードを持たないノードを指します。
アイデア分析:
上の最大の深さを求めるのとは異なり、ここでは 3 つの状況で説明します。1 つ目は、ツリーに右のサブツリーのみがあり、左のサブツリーがない場合、戻り値は右のサブツリーからのトラバースの結果です。左のサブツリーのみです ツリーに右のサブツリーがない場合、返される深さは左のサブツリーの走査の結果です。左と右の両方のサブツリーがある場合、返される深さは小さい値です。
コード:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int minDepth(struct TreeNode* root){
if(!root){
return 0;
}
else if(!root->left&&root->right)
return minDepth(root->right)+1;
else if(!root->right&&root->left)
return minDepth(root->left)+1;
else {
int l=minDepth(root->left);
int r= minDepth(root->right);
if(l>r)
return r+1;
else
return l+1;
}
}
5. バイナリツリーの事前順序走査
バイナリ ツリーのルート ノードを指定すると 、
root
そのノード値の 事前順序 トラバーサルを返します。
アイデア分析:
これはインオーダー トラバーサルと同じです。最初にデータを格納するための配列スペースを割り当て、次にプレオーダー トラバーサルのプロセスに入り、トラバース中にデータを格納します。最終的なトラバーサル結果は、この配列に格納されているデータを直接出力します。
コード:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
void travel(struct TreeNode* root, int *num,int* returnSize)
{
if(!root)
return;
num[*returnSize]=root->val;
*returnSize+=1;
travel(root->left,num,returnSize);
travel(root->right,num,returnSize);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int* num=(int*)malloc(sizeof(int)*100);
*returnSize=0;
travel(root,num,returnSize);
return num;
}
6. バイナリツリーの事後走査
バイナリ ツリーのルート ノードを指定すると 、
root
そのノード値の 事後探索を 返します。
アイデア分析:
この方法は依然として上記と同じであり、現在の事後順序走査の結果を格納するデータ配列を格納するためのスペースを割り当てます。
コード:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
void travel(struct TreeNode* root, int *num,int* returnSize)
{
if(!root)
return;
travel(root->left,num,returnSize);
travel(root->right,num,returnSize);
num[*returnSize]=root->val;
*returnSize+=1;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize){
int *num=(int*)malloc(sizeof(int)*500);
*returnSize=0;
travel(root,num,returnSize);
return num;
}
7. 対称二分木
二分木のルート ノードが与えられた場合
root
、それが軸対称であるかどうかを確認します。
アイデア分析:
二分木が対称二分木かどうかを判断するには、ルートノードを対称軸として分割して比較することになりますが、これについてもいくつかの場合に分けて説明します。1. このとき、対称位置にあるノードがすべて空であれば、結果は true になります; 2. 対称位置にあるノードの一方が空で、もう一方が空でない場合、結果は false; 3.対称位置にあるノードの値が異なる場合、結果も false; 4. 最後に、対称位置にあるノードが存在し、内部のデータ値が同じである場合は、下方向にトラバースし、最後に結果を合計します。
コード:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool check(struct TreeNode* p,struct TreeNode* q){
if(!p&&!q)
return true;
if(p==NULL||!q)
return false;
if(p->val!=q->val)
return false;
else
return check(p->left,q->right)&&check(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root){
return check(root,root);
}
さて、この号の練習問題はこれですべてです。次号でお会いしましょう!
壁紙を共有する: