遍历树数据结构,在一个循环中找到它的高度和计数元素
Walk tree data structure to find its height and count elements in one loop
我有一个树结构。
class Element {
private List<Element> children;
}
Element treeStructure = produceSomeTreeStructure();
//How to get its height and number of elements.
直接的解决方案是制作两个循环。首先我可以找到节点数
A question on getting number of nodes in a Binary Tree
(为非二叉树改变这个算法),
第二个循环获取树的高度
http://www.geeksforgeeks.org/iterative-method-to-find-height-of-binary-tree/
再次将此算法应用于非二叉树。
我的问题是,如何一步完成。将结果保存在全局变量中对我来说是可以接受的。
如果您想知道节点数,则需要探索整棵树。最简单的方法是使用深度优先搜索,即边走边计算节点数。
深度优先搜索算法还可以很容易地计算出当前正在探索的深度,以及总体上达到的最大深度。修改深度优先搜索算法以将这两个作为参数。
如果您以递归方式对其进行编码(最简单),则每次进行递归调用时只需将深度参数加一即可。如果这为您提供的数字大于您跟踪的最大值,则将最大值更新为当前深度。
是的,可以按照下面的代码所示完成。只需添加计数器 totalNodeCount
并在每次以 BFS 样式遍历节点时执行 +1
。
// Iterative method to find height and node-count of Binary Tree
int treeHeightAndNumOfNodes(node *root)
{
// Base Case
if (root == NULL)
return 0;
// Create an empty queue for level order tarversal
queue<node *> q;
// Enqueue Root and initialize height
q.push(root);
int height = 0;
int totalNodeCount = 0; // <-- Use this counter to store total number of node traversed.
while (1)
{
// nodeCount (queue size) indicates number of nodes
// at current lelvel.
int nodeCount = q.size();
if (nodeCount == 0)
return height;
height++;
// Dequeue all nodes of current level and Enqueue all
// nodes of next level
while (nodeCount > 0)
{
node *node = q.front();
q.pop();
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
nodeCount--;
totalNodeCount++; // <-- Update this counter
}
}
}
Again, adapt this algorithm to non-binary tree.
为此,将下面给出的代码行替换为遍历每个子节点并将 NON-NULL 子节点推入队列的循环。
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
你要找的有点像 BFS。你只需要像下面这样走你的树:
int getHeight(Element e) {
int max_height = 0;
for (Element child : e.children) {
max_height = max(max_height, getHeight(child));
}
return max_height + 1;
}
同样,获取元素总数也很容易:无需获取节点子节点中的最大值,只需将它们相加即可。
int getTotalCount(Element e) {
int total_count = 0;
for (Element child : e.children) {
total_count += getTotalCount(el);
}
return total_count + 1;
}
如果您必须 return 使用相同函数的两个数字,只需将它们打包在一个公共 class 中以便仅遍历您的树一次。
感谢大家的回答。
这就是我编写的代码。
public static TreeData countElementsAndFindHeight(Element root) {
TreeData treePair = new TreeData();
if (root == null) {
return treePair;
}
treePair.nElements = 1;
treePair.height = 1;
//Nodes queue will contain all the elements of the trees, so its size is the number of elements.
List<Element> nodesQueue = new LinkedList<Element>();
treePair.walkedNodes = nodesQueue;
List<Element> children = root.getChildren();
if (CommonUtils.isCollectionEmpty(children)) {
return treePair;
}
treePair.height = countElementsAndFindHeight(root, nodesQueue);
nodesQueue.add(root);
treePair.nElements = nodesQueue.size();
return treePair;
}
private static int countElementsAndFindHeight(Element root, List<Element> nodesQueue) {
int maxHeight = 1;
List<Element> children = root.getChildren();
if (CommonUtils.isCollectionEmpty(children)) {
return maxHeight;
}
for (Element childElement : children) {
int childHeight = countElementsAndFindHeight(childElement, nodesQueue);
if (childHeight > maxHeight) {
maxHeight = childHeight;
}
nodesQueue.add(childElement);
}
return maxHeight + 1;
}
public static class TreeData {
protected int height = 0;
protected int nElements = 0;
}
我有一个树结构。
class Element {
private List<Element> children;
}
Element treeStructure = produceSomeTreeStructure();
//How to get its height and number of elements.
直接的解决方案是制作两个循环。首先我可以找到节点数
A question on getting number of nodes in a Binary Tree (为非二叉树改变这个算法),
第二个循环获取树的高度 http://www.geeksforgeeks.org/iterative-method-to-find-height-of-binary-tree/
再次将此算法应用于非二叉树。
我的问题是,如何一步完成。将结果保存在全局变量中对我来说是可以接受的。
如果您想知道节点数,则需要探索整棵树。最简单的方法是使用深度优先搜索,即边走边计算节点数。
深度优先搜索算法还可以很容易地计算出当前正在探索的深度,以及总体上达到的最大深度。修改深度优先搜索算法以将这两个作为参数。
如果您以递归方式对其进行编码(最简单),则每次进行递归调用时只需将深度参数加一即可。如果这为您提供的数字大于您跟踪的最大值,则将最大值更新为当前深度。
是的,可以按照下面的代码所示完成。只需添加计数器 totalNodeCount
并在每次以 BFS 样式遍历节点时执行 +1
。
// Iterative method to find height and node-count of Binary Tree
int treeHeightAndNumOfNodes(node *root)
{
// Base Case
if (root == NULL)
return 0;
// Create an empty queue for level order tarversal
queue<node *> q;
// Enqueue Root and initialize height
q.push(root);
int height = 0;
int totalNodeCount = 0; // <-- Use this counter to store total number of node traversed.
while (1)
{
// nodeCount (queue size) indicates number of nodes
// at current lelvel.
int nodeCount = q.size();
if (nodeCount == 0)
return height;
height++;
// Dequeue all nodes of current level and Enqueue all
// nodes of next level
while (nodeCount > 0)
{
node *node = q.front();
q.pop();
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
nodeCount--;
totalNodeCount++; // <-- Update this counter
}
}
}
Again, adapt this algorithm to non-binary tree.
为此,将下面给出的代码行替换为遍历每个子节点并将 NON-NULL 子节点推入队列的循环。
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
你要找的有点像 BFS。你只需要像下面这样走你的树:
int getHeight(Element e) {
int max_height = 0;
for (Element child : e.children) {
max_height = max(max_height, getHeight(child));
}
return max_height + 1;
}
同样,获取元素总数也很容易:无需获取节点子节点中的最大值,只需将它们相加即可。
int getTotalCount(Element e) {
int total_count = 0;
for (Element child : e.children) {
total_count += getTotalCount(el);
}
return total_count + 1;
}
如果您必须 return 使用相同函数的两个数字,只需将它们打包在一个公共 class 中以便仅遍历您的树一次。
感谢大家的回答。
这就是我编写的代码。
public static TreeData countElementsAndFindHeight(Element root) {
TreeData treePair = new TreeData();
if (root == null) {
return treePair;
}
treePair.nElements = 1;
treePair.height = 1;
//Nodes queue will contain all the elements of the trees, so its size is the number of elements.
List<Element> nodesQueue = new LinkedList<Element>();
treePair.walkedNodes = nodesQueue;
List<Element> children = root.getChildren();
if (CommonUtils.isCollectionEmpty(children)) {
return treePair;
}
treePair.height = countElementsAndFindHeight(root, nodesQueue);
nodesQueue.add(root);
treePair.nElements = nodesQueue.size();
return treePair;
}
private static int countElementsAndFindHeight(Element root, List<Element> nodesQueue) {
int maxHeight = 1;
List<Element> children = root.getChildren();
if (CommonUtils.isCollectionEmpty(children)) {
return maxHeight;
}
for (Element childElement : children) {
int childHeight = countElementsAndFindHeight(childElement, nodesQueue);
if (childHeight > maxHeight) {
maxHeight = childHeight;
}
nodesQueue.add(childElement);
}
return maxHeight + 1;
}
public static class TreeData {
protected int height = 0;
protected int nElements = 0;
}