示例#1
0
static void updateHeight(TreeNode * node)
{
	if(nodeHeight(node->left) > nodeHeight(node->right))
		node->height = nodeHeight(node->left) + 1;
	else
		node->height = nodeHeight(node->right) + 1;
}
示例#2
0
static int calcLoadBalance(TreeNode * leftNode, TreeNode * rightNode)
{
	int leftHeight = nodeHeight(leftNode);
	int rightHeight = nodeHeight(rightNode);

	int heightDifference = leftHeight - rightHeight;

	return heightDifference;
}
int nodeHeight(struct TreeNode* root) {
    if (!root) {
        return 0;
    }
    
    int left = nodeHeight(root->left);
    if (left == -1) {
        return -1;
    }
    
    int right = nodeHeight(root->right);
    if (right == -1) {
        return -1;
    }
    
    if (left - right > 1 || left - right <  -1) {
        return -1;
    }
    
    return left > right ? left + 1 : right + 1;
}
bool isBalanced(struct TreeNode* root) {
    if (nodeHeight(root) == -1) {
        return false;
    }
    return true;
}
示例#5
0
void Tree::buildByUPGMA (const vguard<string>& nodeName, const vguard<vguard<TreeBranchLength> >& distanceMatrix) {
  // check that there are more than 2 nodes
  Assert (nodeName.size() >= 2, "Fewer than 2 nodes; can't make a binary tree");
  // clear the existing tree
  node.clear();
  // copy distance matrix
  vguard<vguard<TreeBranchLength> > dist = distanceMatrix;
  // estimate tree by UPGMA
  // first, initialise the list of active nodes
  set<TreeNodeIndex> activeNodes;
  for (TreeNodeIndex n = 0; n < (int) nodeName.size(); ++n) {
    activeNodes.insert (n);
    node.push_back (TreeNode());
    node.back().name = nodeName[n];
    node.back().parent = -1;
  }
  // main loop
  vguard<TreeBranchLength> nodeHeight (nodeName.size(), 0);
  while (true)
    {
      // get number of active nodes
      const int nActiveNodes = activeNodes.size();
      // loop exit test
      if (nActiveNodes == 2) break;
      Assert (nActiveNodes > 2, "Fewer than 2 nodes left -- should never get here");
      // find closest two nodes
      bool isFirstPair = true;
      TreeBranchLength minDist = 0;
      TreeNodeIndex min_i = -1, min_j = -1;
      set<TreeNodeIndex>::const_iterator node_i_p, node_j_p, activeNodes_end_p;
      activeNodes_end_p = activeNodes.end();
      for (node_i_p = activeNodes.begin(); node_i_p != activeNodes_end_p; ++node_i_p)
	for (node_j_p = node_i_p, ++node_j_p; node_j_p != activeNodes_end_p; ++node_j_p) {
	  const TreeBranchLength d = dist [*node_i_p] [*node_j_p];
	  if (isFirstPair || d < minDist)
	    {
	      min_i = *node_i_p;
	      min_j = *node_j_p;
	      minDist = d;
	      isFirstPair = false;
	    }
	}
      // nodes min_i and min_j are neighbors -- join them with new index k
      // first, calculate new distances
      const TreeNodeIndex k = nodes();
      dist.push_back (vguard<TreeBranchLength> (k + 1));
      dist[k][k] = 0;
      const TreeBranchLength d_ij = dist[min_i][min_j];
      nodeHeight.push_back (max (nodeHeight[min_i] + minBranchLength,
				 max (nodeHeight[min_j] + minBranchLength,
				      (nodeHeight[min_i] + nodeHeight[min_j] + d_ij) / 2)));
      const TreeBranchLength d_ik = nodeHeight[k] - nodeHeight[min_i];
      const TreeBranchLength d_jk = nodeHeight[k] - nodeHeight[min_j];
      for (TreeNodeIndex m = 0; m < k; ++m)
	dist[m].push_back (dist[k][m] = (dist[min_i][m] + dist[min_j][m]) / 2);
      dist[min_i][k] = dist[k][min_i] = d_ik;
      dist[min_j][k] = dist[k][min_j] = d_jk;
      // now update the Tree
      node.push_back (TreeNode());
      node[k].child.push_back (min_i);
      node[k].child.push_back (min_j);
      node[min_i].parent = k;
      node[min_i].d = max (0., d_ik);
      node[min_j].parent = k;
      node[min_j].d = max (0., d_jk);
      LogThisAt(7,"Joining nodes " << min_i << " and " << min_j << " to common ancestor " << k << " (branch lengths: " << k << "->" << min_i << " = " << d_ik << ", " << k << "->" << min_j << " = " << d_jk << ")" << endl);
      activeNodes.erase (min_i);
      activeNodes.erase (min_j);
      activeNodes.insert (k);
    }
  // make the root node
  set<TreeNodeIndex>::iterator iter = activeNodes.begin();
  const TreeNodeIndex i = *iter;
  const TreeNodeIndex j = *++iter;
  const TreeNodeIndex k = node.size();
  nodeHeight.push_back (max (nodeHeight[i] + minBranchLength,
			     max (nodeHeight[j] + minBranchLength,
				  (nodeHeight[i] + nodeHeight[j] + dist[i][j]) / 2)));
  node.push_back (TreeNode());
  node[k].parent = -1;
  node[k].child.push_back (i);
  node[k].child.push_back (j);
  node[i].parent = k;
  node[i].d = max (0., nodeHeight[k] - nodeHeight[i]);
  node[j].parent = k;
  node[j].d = max (0., nodeHeight[k] - nodeHeight[j]);

  const string s = toString();
  LogThisAt(5,"UPGMA tree: " << s << endl);
  parse (s);  // to ensure consistency (i.e. serializing & deserializing will not change node indices)

  assertUltrametric();
}