简体   繁体   English

该算法的时间复杂度是多少?

[英]What would the time complexity of this algorithm be?

Good day, I'm trying to improve my abilities with Big-O, and I wrote a Java algorithm to print a tree to the console. 美好的一天,我正在尝试使用Big-O来提高自己的能力,并且我编写了一种Java算法来在控制台上打印树。

public static void printTree(Tree tree){
    int height = getHeight(tree);
    int maxWidth = (int)Math.pow(2, height) - 1;
    HashMap<Coordinate, Integer> coordinates = getTreeCoordinates(tree, maxWidth/(int)Math.pow(2, 1) + 1, 1, maxWidth);
    printCoordinatesToConsole(coordinates, maxWidth, height);
}

static void printCoordinatesToConsole(HashMap<Coordinate, Integer> coordinates, int width, int height){
    for (int j = 1; j <= height; j++){
        for (int i = 1; i <= width; i++){
            if (coordinates.containsKey(new Coordinate(i, j)))
                System.out.print(coordinates.get(new Coordinate(i, j)));
            else
                System.out.print(' ');
        }
        System.out.print("n\n");
    }
}

static HashMap<Coordinate, Integer> getTreeCoordinates(Tree tree, int x, int y, int maxWidth){
    HashMap<Coordinate, Integer> result = new HashMap<>();
    result.put(new Coordinate(x, y), tree.data);
    if (tree.left == null && tree.right == null){
        return result;
    }
    else if (tree.left == null){
        result.putAll(getTreeCoordinates(tree.right, x+maxWidth/(int)Math.pow(2, y+1) + 1, y+1, maxWidth));
        return result;
    }
    else if (tree.right == null){
        result.putAll(getTreeCoordinates(tree.left, x-maxWidth/(int)Math.pow(2, y+1) - 1, y+1, maxWidth));
        return result;
    }
    else{
        result.putAll(getTreeCoordinates(tree.right, x+maxWidth/(int)Math.pow(2, y+1) + 1, y+1, maxWidth));
        result.putAll(getTreeCoordinates(tree.left, x-maxWidth/(int)Math.pow(2, y+1) - 1, y+1, maxWidth));
        return result;
    }
}

As far as I can tell, the complexity would be based on: 据我所知,复杂度将基于:

1.Finding tree height O(n) 1.发现树高O(n)

2.Storing the coordinates for all elements in the hashmap O(n) 2在哈希图中存储所有元素的坐标O(n)

3.Printing the coordinates to the screen O(width*height) 3.将坐标打印到屏幕O(宽*高)

Now, since width is 2^height, which in the worst case would be n, does this mean the time complexity is O(n*2^n)? 现在,由于width为2 ^ h,在最坏的情况下为n,这是否意味着时间复杂度为O(n * 2 ^ n)? Also, if I were to ignore the printing (or if I were to print directly to the coordinates on the console rather than iterating through all of the width/height), would the complexity then be O(n) 另外,如果我忽略打印(或者如果我直接在控制台上打印到坐标,而不是遍历所有宽度/高度),那么复杂度将为O(n)

Thank you! 谢谢!

  1. Finding tree height is O(n). 发现树的高度为O(n)。

If getHeight is more or less the following, it will be O(n), where n is the number of nodes in the tree: 如果getHeight大致等于以下值,则它将为O(n),其中n是树中的节点数:

static int getHeight(Tree tree) {
    if (tree == null) {
        return 0;
    }

    return 1 + max(getHeight(tree.left, tree.right));
}
  1. Storing the coordinates for all elements in the hash map O( getTreeCoordinates ) = O( height * n) right now, but can be improved to O(n). 现在将哈希图中所有元素的坐标存储为O( getTreeCoordinates )= O( height * n),但可以将其改进为O(n)。

O( HashMap.putAll ) technically depends on implementation, but is almost certainly linear in the number of elements! O( HashMap.putAll )在技术上取决于实现,但是几乎可以肯定,元素数量是线性的! Instead of using HashMap.putAll , you can pass the HashMap down to the recursive calls, eg: 代替使用HashMap.putAll ,您可以将HashMap向下传递给递归调用,例如:

static HashMap<Coordinate, Integer> getTreeCoordinates(Tree tree, int x, int y, int maxWidth){
    HashMap<Coordinate, Integer> result = new HashMap<>();
    return getTreeCoordinatesImpl(tree, x, y, maxWidth, result);
}

static void getTreeCoordinatesImpl(Tree tree, int x, int y, int maxWidth, HashMap<Coordinate, Integer> result){
    result.put(new Coordinate(x, y), tree.data);
    if (tree.right != null){
        getTreeCoordinatesImpl(tree.right, x+maxWidth/(int)Math.pow(2, y+1) + 1, y+1, maxWidth, result);
    }
    if (tree.left != null){
        getTreeCoordinatesImpl(tree.left, x-maxWidth/(int)Math.pow(2, y+1) - 1, y+1, maxWidth, result);
    }
}
  1. Printing the coordinates to the screen is O( height * width ). 在屏幕上打印坐标为O( height * width )。 It will be O(n), where n is the number of nodes is the tree, if you iterate over the HashMap instead of over all (x, y) coordinates. 如果您在HashMap而不是所有(x,y)坐标上进行迭代,则它将是O(n),其中n是节点的数目是树。

Both O( HashMap.containsKey ) and O( HashMap.get ) are 1 (constant time). O( HashMap.containsKey )和O( HashMap.get )均为1(恒定时间)。 To be precise, they're amortized constant in time - on average, they take a constant time, but a single run can be linear in the number of elements of the hash map in the rare worst case. 确切地说,它们是按时间摊销的-平均而言,它们花费的时间是恒定的,但是在极少见的最坏情况下,一次运行就可以使哈希映射的元素数量呈线性关系。

In big O notation all constants are equivalent (O(1) is equivalent to O(2)). 在大O表示法中,所有常数都等效(O(1)等于O(2))。 So: 所以:

O( printCoordinatesToConsole ) = O( printCoordinatesToConsole )=

O( height ) * O( width ) * (O( HashMap.containsKey ) + O( HashMap.get )) = O( height )* O( width )*(O( HashMap.containsKey )+ O( HashMap.get ))=

O( height ) * O( width ) * O(1) = O( height )* O( width )* O(1)=

O( height * width ) O( height * width


Now, since width is 2^height, which in the worst case would be n, does this mean the time complexity is O(n*2^n)? 现在,由于width为2 ^ h,在最坏的情况下为n,这是否意味着时间复杂度为O(n * 2 ^ n)?

Let's do the math (n is the number of nodes in the tree, I assume getTreeCoordinates is edited as described above): 让我们做一下数学运算(n是树中的节点数,我假设getTreeCoordinates进行了编辑):

O( printTree ) = O( printTree )=

O( getHeight ) + O( getTreeCoordinates ) + O( printCoordinatesToConsole ) = O( getHeight )+ O( getTreeCoordinates )+ O( printCoordinatesToConsole )=

O(n) + O(n) + O( height * width ) O(n)+ O(n)+ O( height * width

Since height * width >= n: 由于height * width > = n:

O( printTree ) = O( height * width ) O( printTree )= O( height * width


Also, if I were to ignore the printing (or if I were to print directly to the coordinates on the console rather than iterating through all of the width/height), would the complexity then be O(n) 另外,如果我忽略打印(或者如果我直接在控制台上打印到坐标,而不是遍历所有宽度/高度),那么复杂度将为O(n)

Yes, then the above equation becomes either (no printing): 是的,那么上面的等式变为(不打印):

O( printTree ) = O( getHeight ) + O( getTreeCoordinates ) = O(n) + O(n) = O(n) O( printTree )= O( getHeight )+ O( getTreeCoordinates )= O(n)+ O(n)= O(n)

or (printing with iteration over the hash map of nodes): 或(在节点的哈希图上迭代打印):

O( printTree ) = O( getHeight ) + O( getTreeCoordinates ) + O(n) = O(n) O( printTree )= O( getHeight )+ O( getTreeCoordinates )+ O(n)= O(n)


It will be helpful if you include the definitions of Tree , Coordinate and getHeight , and if applicable, the contents of tree . 如果您包括TreeCoordinategetHeight的定义,以及tree的内容(如果适用),将很有帮助。 You can also use an online playground like ideone.com to provide a runnable example. 您也可以使用ideone.com这样的在线游乐场来提供可运行的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM