バイナリ検索ツリーの高さを見つけるためにこの方法をやり直すのを手伝ってくれる人がいるかどうか疑問に思っていました。これまでのところ、私のコードはこのように見えます。ただし、得られる答えは実際の高さよりも1大きくなります。ただし、returnステートメントから+1を削除すると、実際の高さよりも1小さくなります。これらのBST。どんな助けでも大歓迎です。
public int findHeight(){
if(this.isEmpty()){
return 0;
}
else{
TreeNode<T> node = root;
return findHeight(node);
}
}
private int findHeight(TreeNode<T> aNode){
int heightLeft = 0;
int heightRight = 0;
if(aNode.left!=null)
heightLeft = findHeight(aNode.left);
if(aNode.right!=null)
heightRight = findHeight(aNode.right);
if(heightLeft > heightRight){
return heightLeft+1;
}
else{
return heightRight+1;
}
}
問題はベースケースにあります。
「ツリーの高さは、ルートからツリー内の最も深いノードまでのパスの長さです。ノード(ルート)のみを持つ(ルート化された)ツリーの高さはゼロです。」 - ウィキペディア
ノードがない場合、0ではなく-1を返します。これは、最後に1を追加しているためです。
したがって、ノードがない場合は、-1を返し、+ 1をキャンセルします。
int findHeight(TreeNode<T> aNode) {
if (aNode == null) {
return -1;
}
int lefth = findHeight(aNode.left);
int righth = findHeight(aNode.right);
if (lefth > righth) {
return lefth + 1;
} else {
return righth + 1;
}
}
バイナリ検索ツリーの高さはnumber of layers - 1
と等しくなります。
http://en.wikipedia.org/wiki/Binary_tree の図を参照してください
再帰は良好なので、ルートレベルで1を引くだけです。
また、nullノードを処理することにより、関数を少しクリーンアップできることに注意してください。
int findHeight(node) {
if (node == null) return 0;
return 1 + max(findHeight(node.left), findHeight(node.right));
}
int getHeight(Node node) {
if (node == null) return -1;
return 1 + Math.max(getHeight(node.left), getHeight(node.right));
}
IMO、あなたのコードは少し単純化されることで恩恵を受けるでしょう。子ポインターがヌルの場合に再帰を終了するのではなく、currentポインターがヌルの場合にのみ再帰を終了します。これにより、コードがlotに記述しやすくなります。擬似コードでは、次のようになります。
if (node = null)
return 0;
else
left = height(node->left);
right = height(node->right);
return 1 + max(left, right);
ワンラインソリューションが好きな私のような人々のために:
public int getHeight(Node root) {
return Math.max(root.left != null ? getHeight(root.left) : -1,
root.right != null ? getHeight(root.right) : -1)
+ 1;
}
class Solution{
public static int getHeight(Node root) {
int height = -1;
if (root == null) {
return height;
} else {
height = 1 + Math.max(getHeight(root.left), getHeight(root.right));
}
return height;
}
これはテストされていませんが、かなり明らかに正しいです:
private int findHeight(Treenode aNode){ if(aNode.left == null && aNode.right == null){ return 0; // 1でした;明らかに子のないノードの高さは0です。 } else if(aNode.left == null){ return 1 + findHeight(aNode.right); } else if(aNode.right == null){ return 1 + findHeight(aNode.left); } else { return 1 + max(findHeight(aNode.left) 、findHeight(aNode.right)); } }
多くの場合、コードを単純化する方が、コードが1つずれている理由を理解するよりも簡単です。このコードは理解しやすいです:考えられる4つのケースは、明らかに正しい方法で明確に処理されます。
簡潔でうまくいけばそれを表現する正しい方法を次に示します。
private int findHeight(TreeNode<T> aNode){
if(aNode == null || (aNode.left == null && aNode.right == null))
return 0;
return Math.max(findHeight(aNode.left), findHeight(aNode.right)) + 1;
}
現在のノードがnullの場合、ツリーはありません。両方の子がある場合、単一のレイヤーがあります。これは、高さが0であることを意味します。これは、層の数として高さの定義(Stephenが言及)を使用します-1
public void HeightRecursive()
{
Console.WriteLine( HeightHelper(root) );
}
private int HeightHelper(TreeNode node)
{
if (node == null)
{
return -1;
}
else
{
return 1 + Math.Max(HeightHelper(node.LeftNode),HeightHelper(node.RightNode));
}
}
C#コード。これら2つのメソッドをBSTクラスに含めます。木の高さを計算するには2つの方法が必要です。 HeightHelperはそれを計算し、HeightRecursiveはmain()で印刷します。
上記の高さの定義は正しくありません。それが深さの定義です。
「ツリーのノードの深さMは、ツリーのルートからMへのパスの長さです。ツリーの高さは1ですツリー内の最も深いノードの深さより深さdのすべてのノードは、ツリー内のレベルdにあります。ルートは、レベル0の唯一のノードです。その深さは0です。」
引用:「データ構造とアルゴリズム分析の実践的な紹介」第3.2版(Javaバージョン)Clifford A. Shafferコンピュータサイエンス学科Virginia Tech Blacksburg、VA 24061
public int height(){
if(this.root== null) return 0;
int leftDepth = nodeDepth(this.root.left, 1);
int rightDepth = nodeDepth(this.root.right, 1);
int height = leftDepth > rightDepth? leftDepth: rightDepth;
return height;
}
private int nodeDepth(Node node, int startValue){
int nodeDepth = 0;
if(node.left == null && node.right == null) return startValue;
else{
startValue++;
if(node.left!= null){
nodeDepth = nodeDepth(node.left, startValue);
}
if(node.right!= null){
nodeDepth = nodeDepth(node.right, startValue);
}
}
return nodeDepth;
}
int height(Node* root) {
if(root==NULL) return -1;
return max(height(root->left),height(root->right))+1;
}
左右のサブツリーから最大の高さを取得し、それに1を追加します。これは、ベースケースも処理します(1ノードのツリーの高さは0です)。
TempHeightを静的変数として設定します(初期値は0)。
static void findHeight(Node node、int count){
if (node == null) {
return;
}
if ((node.right == null) && (node.left == null)) {
if (tempHeight < count) {
tempHeight = count;
}
}
findHeight(node.left, ++count);
count--; //reduce the height while traversing to a different branch
findHeight(node.right, ++count);
}
この質問は2つの異なることを意味すると思います...
高さは最長ブランチのノード数:-
int calcHeight(node* root){ if(root==NULL) return 0; int l=calcHeight(root->left); int r=calcHeight(root->right); if(l>r) return l+1; else return r+1; }
高さはツリー内のノードの総数それ自体です:
int calcSize(node* root){ if(root==NULL) return 0; return(calcSize(root->left)+1+calcSize(root->right)); }
Javaのソリューションは少し長くなりますが機能します。
public static int getHeight (Node root){
int lheight = 0, rheight = 0;
if(root==null) {
return 0;
}
else {
if(root.left != null) {
lheight = 1 + getHeight(root.left);
System.out.println("lheight" + " " + lheight);
}
if (root.right != null) {
rheight = 1+ getHeight(root.right);
System.out.println("rheight" + " " + rheight);
}
if(root != null && root.left == null && root.right == null) {
lheight += 1;
rheight += 1;
}
}
return Math.max(lheight, rheight);
}
C#のソリューションを次に示します
private static int heightOfTree(Node root)
{
if (root == null)
{
return 0;
}
int left = 1 + heightOfTree(root.left);
int right = 1 + heightOfTree(root.right);
return Math.Max(left, right);
}
int getHeight(Node* root)
{
if(root == NULL) return -1;
else return max(getHeight(root->left), getHeight(root->right)) + 1;
}
public int getHeight(Node node)
{
if(node == null)
return 0;
int left_val = getHeight(node.left);
int right_val = getHeight(node.right);
if(left_val > right_val)
return left_val+1;
else
return right_val+1;
}
// BSTの高さを見つける関数
int height(Node* root) {
if(root == NULL){
return -1;
}
int sum=0;
int rheight = height(root->right);
int lheight = height(root->left);
if(lheight>rheight){
sum = lheight +1;
}
if(rheight > lheight){
sum = rheight + 1;
}
return sum;
}
Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest、およびClifford Steinによる「Introduction to Algorithms」によれば、以下は木の高さの定義です。
ツリー内のノードの高さは、ノードからリーフまでの最も長い単純な下向きパス上のエッジの数であり、ツリーの高さはそのルートの高さです。ツリーの高さは、ツリー内のノードの最大の深さに等しくなります。
以下は私のRubyソリューションです。ほとんどの人は、実装で空のツリーまたは単一ノードのツリーの高さを忘れていました。
def height(node, current_height)
return current_height if node.nil? || (node.left.nil? && node.right.nil?)
return [height(node.left, current_height + 1), height(node.right, current_height + 1)].max if node.left && node.right
return height(node.left, current_height + 1) if node.left
return height(node.right, current_height + 1)
end
これを読む他の人のために!!!!
HEIGHTは、ルートノードからリーフノードまでの最長パスのノード数として定義されます。したがって、ルートノードのみを持つツリーの高さは0ではなく1です。
特定のノードのLEVELは、ルートから1を足した距離に1を加えたものです。したがって、ルートはレベル1、その子ノードはレベル2などになります。
(情報構造:Javaを使用した抽象化と設計、第2版、Elliot B. KoffmanおよびPaul A. T. Wolfgang著)-現在コロンバス州立大学で受講しているデータ構造コースで使用される本。
int maxDepth(BinaryTreeNode root) {
if(root == null || (root.left == null && root.right == null)) {
return 0;
}
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}