簡體   English   中英

在java問題中將節點插入二叉樹中

[英]inserting nodes into a binary tree in java question

即時通訊從c ++到java,我在二進制樹上與java混淆。 讓Node類成為內部靜態類的唯一方法是什么? 我看到的所有例子都是這樣做的。 但是,我這樣做的方式是我有一個節點類,而binarytree類使用這個節點類。 但是當我在第二次插入后嘗試插入樹時,我一直收到錯誤。 if(dataIn <= nodeIn.getLeft().getData()){我在此行獲得異常

我很困惑我做錯了什么....這是我的插入代碼我有。 提前致謝..

public void insert(int dataIn){
    root = insert(root, dataIn);
}

private Node insert(Node nodeIn, int dataIn){
    if(nodeIn==null){
        nodeIn = new Node(null, null, dataIn);
    }else{
        if(dataIn <= nodeIn.getLeft().getData()){
            nodeIn.setLeft(insert(nodeIn.getLeft(), dataIn));
        }else{
            nodeIn.setRight(insert(nodeIn.getRight(), dataIn));
        }
    }

    return nodeIn;
}

令人困惑的部分原因是“Node”不應該是insert方法的參數,您應該調用node中定義的insert方法。

所以,假設您在“普通代碼”中保留“Root”節點 - 讓我們稱之為“rootNode”只是為了模糊。

好的,所以你插入樹的代碼是:

rootNode.insert(newValue);

很容易。

現在來定義該方法。

public class Node {
    private int value;
    private Node lower;
    private Node higher;

    public void insert(int newValue) {
        if (newValue < value)
            if(lower == null)
                lower=new Node(value);
            else
                lower.insert(newValue);
        else
            if(higher == null)
                higher=new Node(value);
            else
                higher.insert(newValue);
      }

 // and you'll need a constructor
    public Node(int value) {
        this.value=value;
    }
}

這應該更清楚地閱讀。 我打算點擊“Post”然后我要編輯它並弄清楚如何輕松折射邪惡的邪惡復制和粘貼代碼。

再想一想,我會留在那里,因為它更具可讀性。 我能看到的最好的解決方案是使節點成為一個數組,然后你得到:

public class Node {

    private int value;
    private Node[] nodes=new Node[2];
    private final int LOWER=0;
    private final int HIGHER=1;

    public void insert(int newValue) {
        int index=LOWER;
        if (newValue > value)
            index=HIGHER;

        if(nodes[index] == null)
            nodes[index]=new Node(value);
            else
                nodes[index].insert(newValue);
        }
    }

但我不會取代原件,因為正如我所說,它更清晰。

我推薦重構書來解決更多這方面的問題。 一旦你真正獲得OO,它確實有助於簡化你的代碼。 將一個對象傳遞給另一個靜態方法(一個不使用成員變量的方法)是一個死的贈品。

有關@ ted評論和OO的更多考慮因素 - getLeft和getRight甚至不應成為問題。 抽象之外都沒有必要。

一般來說,您可能需要的是Node中的這些方法:

public boolean doesContain(int value) {
     if(value == this.value)
         return true
     else
         return nodes[ this.value < value ? LOWER : HIGHER].doesContain(value);
}

有可能

public void getValuesSorted(LinkedList l) {
    nodes[LOWER].getValuesSorted(l);
    l.put(value);
    nodes[HIGHER].getValuesSorted(l);
}

然后你甚至不需要暴露它是你正在處理的樹 - beter OO抽象。

您需要測試nodeIn.getLeft() == null

您可以使用以下代碼來清楚您的理解。 大多數情況下,我們不使用任何其他類,可以在單個Node類本身內完成所有操作。 這是一個非常基本的例子,我認為可能會有所幫助......當我看到你有兩種方法,你只提供數據而不是root。 相信我最好在你的主類中擁有root。 推理我們在任何需要緩存的地方都很方便。

public Node insert(Node root, Node newNode) {
if (root == null) { 
    root = newNode;
} else {
    if(root.data > newNode.data) {
        root.left = insert(root.left, newNode);
    } else {
        root.right = insert(root.right, newNode);
    }
}
return root;

}

直接從已初始化的任何類中調用此方法。 這是一個樣本plz檢查..

Node root = new Node(10);
    root.insert(root, new Node(5));
    root.insert(root, new Node(3));
    root.insert(root, new Node(6));
    root.insert(root, new Node(1));

讓Node類成為內部靜態類的唯一方法是什么? 我看到的所有例子都是這樣做的。

沒有。

Node類不需要是內部類或嵌套類。 (嚴格來說,“靜態內部”類是嵌套類。)

但是,只有內部或嵌套類可以是private 如果您的Node類是常規類,那么您將向(至少)同一包中的其他類公開實現細節。 這是一個壞主意......這就解釋了為什么你看到Node類的聲明方式。

實際上,對於二叉樹,不需要檢查插入元素是否大於父節點或者不是父節點。 我認為沒有必要檢查這些條件。 我們必須從用戶那里獲取是否向右或向左插入。

public class TreeNode
{
    private int data;
    private TreeNode left;
    private TreeNode right;

    public Tree( )
    {
        data = 0;
        left = null;
        right = null;
    }

    public Tree( int initialInfo, TreeNode initialLeft, TreeNode initialRight )
    {
        data = initialInfo;
        left = initialLeft;
        right = initialRight;
    }

    public void setLeft( TreeNode newLeft )
    {
        left = newLeft;
    }

    public void setRight( TreeNode newRight )
    {
        right = newRight;
    }

    public void insert( int element )
    {
        if( element <= data )
        {
            if( left == null )
                setLeft( new TreeNode( element, null, null ) );
            else
                left.insert( element );
        }
        else
        {
            if( right == null )
                setRight( new TreeNode( element, null, null ) );
            else
                right.insert( element );
        }
    }
}

代替:

if (dataIn <= nodeIn.getLeft().getData()) {

... 你要:

if (dataIn < nodeIn.getData()) {

您需要將要插入的值與當前節點上的值進行比較。

我將<=符號更改為<符號,以避免重復。

所以你重構的代碼是:

public void insert(int dataIn) {
  root = insert(root, dataIn);
}

private Node insert(Node nodeIn, int dataIn){
  if (nodeIn == null) {
    nodeIn = new Node(null, null, dataIn);
  } else {
    if (dataIn < nodeIn.getData()) {
      nodeIn.setLeft(insert(nodeIn.getLeft(), dataIn));
    } else {
      nodeIn.setRight(insert(nodeIn.getRight(), dataIn));
    }
  }
  return nodeIn;
}

您的所有解決方案都沒有考慮到如果要將節點插入樹的中間會發生什么。 你假設它也將是最小的或最大的。 當您在樹的中間插入一些東西時,您將意識到操作變得更加復雜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM