簡體   English   中英

計算樹的高度-Java

[英]Computing the height of a tree - Java

我目前有一種計算樹高的方法,但我需要加快算法的運行時間,使其可以在6秒內運行。 我當時正在考慮實施某種遞歸方法,但不確定如何實現。

public class TreeHeight {
    int n;
    int parent[];

    void read() throws IOException {
        FastScanner in = new FastScanner();
        n = in.nextInt();
        parent = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = in.nextInt();
        }
    }

    int computeHeight() {
                    // Replace this code with a faster implementation
        int maxHeight = 0;
        for (int vertex = 0; vertex < n; vertex++) {
            int height = 0;
            for (int i = vertex; i != -1; i = parent[i])
                height++;
            maxHeight = Math.max(maxHeight, height);// assign the max of the two arguements
        }
        return maxHeight;
    }
}

遞歸解決方案可以是這個樣子,這取決於你如何在內部存儲你的樹。 此解決方案假定您有一個Node類,該類具有與其所有子節點的鏈接。

該代碼執行的是,它從根開始遞歸地計算樹中向下的每個路徑的高度(或實際深度),並選擇最長的路徑。

int computeHeight(Node root){
    int levels = 0;
    for(Node child : root.children){
        int childHeight = computeHeight(child);
        if(childHeight > levels){
            levels = childHeight;
        }
    }
    return levels + 1;
}

您可以使用記憶來改善算法。 我已經使用數組heights存儲已經計算的結果。 每當計算結果時,它就會存儲在數組中,而不會再次計算。 對於大型數組,這可以使您的算法明顯更快。

int computeHeight() {
    int maxHeight = 0;
    int[] heights = new int[parent.length];
    for (int vertex = 0; vertex < n; vertex++) {
        if (heights[vertex] != 0)       // We've been here before
            continue;
        int height = 0;
        for (int i = vertex; i != -1; i = parent[i]) {
            if (heights[i] != 0) {     // We've been here before 
                height += heights[i];   
                break;
            }
            height++;
        }
        maxHeight = Math.max(maxHeight, height);
        // Now we store the results in the array to save us time in the future.
        for (int i = vertex; i != -1; i = parent[i]) {
            if (heights[i] != 0)
                break;
            heights[i] = height--;
        }
    }
    return maxHeight;
}

如果你有邏輯地思考

樹的高度=最大(左子樹的高度,右子樹的高度)+1

因此,遞歸方法將遞歸計算左右子樹的高度並返回max + 1。

這是函數的樣子

int Height(Node root)
{

    if(root==null)
     return 0;

 int l=Height(root.left);
 int r=Height(root.right);

return max(l,r)+1;
}

看看此遞歸解決方案是否適合您。

對於需要比@Paul Boddington提到的算法更快的算法的任何人,只是后續注釋/注釋。

(一個朋友使用上述算法進行類分配,發現它不夠快不能超過時間限制)。

我們不需要每次都遍歷到根節點,只需在已經計算出的第一個節點處停止。

因此,最重要的區別是兩行:

            while self.heights[i] == 0 and i != -1:

替換以上算法:

        for (int i = vertex; i != -1; i = parent[i]) {

示例Python代碼:

class TreeHeight:
def read(self):
    self.parent = []  // input parent array
    self.n = len(self.parent)
    self.heights = [0] * self.n

def get_root(self):
    return self.parent.index(-1)

def compute_height(self):
    # Replace this code with a faster implementation

    maxHeight = 0
    for vertex in range(self.n):
        if self.heights[vertex] != 0:
            continue

        if self.parent[vertex] == -1:
            self.heights[vertex] = 1

        height = 0
        i = vertex
        while self.heights[i] == 0 and i != -1:
            height += 1
            i = self.parent[i]
        height += self.heights[i]

        maxHeight = max(maxHeight, height)

        i = vertex
        while self.heights[i] == 0 and i != -1:
                  self.heights[i] = height
                  height = height - 1
                  i = self.parent[i]

        print vertex, self.heights[vertex]
        print "maxHeight", maxHeight

    return maxHeight

暫無
暫無

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

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