树操作的复杂性

时间:2015-10-15 08:22:08

标签: java tree complexity-theory

我有这段代码:

package rr.fe.op.lab.proc;

class TreeNode {
    TreeNode left;
    TreeNode right;
    String data;
}

class TreeProgram {
    public static void main(String[] args) {
        TreeNode node = null;
        node = insert(node, "Han");
        node = insert(node, "Luke");
        node = insert(node, "Leia");
        node = insert(node, "Padme");
        node = insert(node, "Vader");
        node = insert(node, "Yoda");

        System.out.println("Writing tree inorder:");
        writeTree(node);

        node = reverseTreeOrder(node);
        System.out.println("Writing reversed tree inorder:");

        writeTree(node);
        int size = sizeOfTree(node);
        System.out.println("Number of nodes in tree is "+size+".");

        boolean found = containsData(node, "Padme");
        System.out.println("Searched element is found: "+found);
    }

    static boolean containsData(TreeNode treeRoot, String data) {
        if(treeRoot == null)
            return false;
        else if(data.compareTo(treeRoot.data) == 0)
        return true;
        else if(data.compareTo(treeRoot.data) < 1)
            return containsData(treeRoot.left,data);
        else 
            return containsData(treeRoot.right,data);
    }

    static int sizeOfTree(TreeNode treeRoot) {
        if(treeRoot == null)
            return 0;
        else 
            return 1 + sizeOfTree(treeRoot.right) + sizeOfTree(treeRoot.left);
    }

    static TreeNode insert(TreeNode treeRoot, String data) {
        if(treeRoot == null){
            TreeNode newnode = new TreeNode();
            newnode.data = data;
            newnode.left = null;
            newnode.right = null;
            return newnode;
        }
        else if (data.compareTo(treeRoot.data) < 1)
            treeRoot.left = insert(treeRoot.left,data);
        else 
            treeRoot.right = insert(treeRoot.right,data);
        return treeRoot;
    }

    static void writeTree(TreeNode treeRoot) {
        if(treeRoot != null){
            writeTree(treeRoot.left);
            System.out.println(treeRoot.data);
            writeTree(treeRoot.right);
        }
    }

    static TreeNode reverseTreeOrder(TreeNode treeRoot) {
        if(treeRoot == null)
            return null;

        TreeNode node = new TreeNode();
        node = treeRoot.left;
        treeRoot.left = treeRoot.right;
        treeRoot.right = node;

        reverseTreeOrder(treeRoot.left);
        reverseTreeOrder(treeRoot.right);
        return treeRoot;
    }
}

我想知道方法containsData的复杂性(大O表示法)。我知道方法containsData不会在每次方法reverseTreeOrder之后找到数据。但是,我想编写方法contansData2,它将100%在树中查找数据,而它是否反转。该方法的复杂性在哪?你能帮我吗?

1 个答案:

答案 0 :(得分:1)

复杂性将是 O(n),因为我始终可以为您提供输入,这将导致每个新元素位于每个前一个节点的右侧(或左侧),从而生成一棵不平衡的树:

输入:a,b,c,d

树:

a
 \
  b
   \
    c
     \
      d

对于大多数输入,树将更加平衡,containsData()将更快,但 O 符号关注最坏情况。

要根据amortized complexity生成 O(log n),您必须rebalance the tree

至于反转树,这会破坏树的不变量,以便containsData()方法在查找数据时使用错误的树分支。一种解决方案是始终搜索整个树,但这将使得正在排序的树的任何好处无效。另一种方法可能是使用&#34; hack&#34; - 查看根,比较根数据和左右儿童的数据,以确定树是否实际被反转,然后使用此信息通过树下降。

最坏情况的复杂性仍然存在于 O(n)