简体   繁体   中英

Given a binary search tree, find the node with largest value of ocurrences

I have a BST declared like this:

struct nodeABB {
   int data;
   int ocurr;
   nodeABB *left;
   nodeABB *right;
};

The "ocurr" value save how many times the same data was inserted in the tree.

I need a recursive algorithm to find the node with the largest "ocurr" value, if there are two nodes with the same value the idea is to return the one with the largest data.

Edit: Mi last try:

trypedef nodeABB* ABB;
ABB Max(ABB a) {
ABB ret = NULL;
  if (!a) 
    return ret;

ABB a1 = Max(a->left);
ABB a2 = Max(a->right);

if (a1 && a2) {
    int n1 = a1->ocurr;
    int n2 = a2->ocurr;
    if (n1 > n2) 
        ret = a1;
    else if (n1 < n2)
        ret = a2;
    else
        ret = (a1->data < a2->data ? a1 : a2);
} else if (!a1 && a2)
     ret = a2;
else if (a1 && !a2)
    ret = a1;

return ret;
}

Assuming data is the tree's sort term, there is no efficient algorithm. You would have to do an exhaustive iteration through all nodes to find the highest value of ocurr . Any full-tree traversal algorithm would work (depth-first, breadth-first, etc.).

It looks like you basically have the right idea, you just need to additionally compare the maximum of the children with the current node (ie compare ret with a ).

Your function can also be simplified a bit, here's my take:

ABB Max(ABB a) {
  // if the current node is NULL, just return NULL
  if (a == NULL)
    return NULL;

  // find the maximums in the left and right subtrees
  ABB a1 = Max(a->left);
  ABB a2 = Max(a->right);

  // make the current node the maximum
  ABB maxN = a;

  // if the current node has a left child and...
  if (a1 != NULL &&
  // the maximum in the left child's subtree > the current maximum or...
      (a1->ocurr > maxN->ocurr ||
  // the maximums are equal and the left subtree's maximum node's bigger
       (a1->ocurr == maxN->ocurr && a1->data > maxN->data)))
  {
    // set the new maximum to be the left subtree's maximum node
    maxN = a1;
  }

  // if the current node has a right child and...
  if (a2 != NULL &&
  // the maximum in the right child's subtree > the current maximum or...
      (a2->ocurr > maxN->ocurr ||
  // the maximums are equal and the right subtree's maximum node's bigger
       (a2->ocurr == maxN->ocurr && a2->data > maxN->data)))
  {
    // set the new maximum to be the right subtree's maximum node
    maxN = a2;
  }

  // return the maximum
  return maxN;
}

If this is a frequently accessed issue, you could "embed" another BST for the data frequency. This would require two extra link fields:

struct nodeABB {
   int data;
   int ocurr;
   nodeABB *left;
   nodeABB *right;
   nodeABB *left_by_occurance;
   nodeABB *right_by_occurance;
};

You would also need another pointer to the start of the "occurances" BST:
nodeABB * occurance_bst;

Another method is to have two BST's with pointers to the node data and a pointer to a comparison function:

struct data
{
  int data;
  int occurrences;
};

struct nodeABB; // forward declaration.
typedef bool (*Comparison_Function_Pointer)(nodeABB * a, nodeABB * b);
struct nodeABB
{
  data * p_data;
  nodeABB * left;
  nodeABB * right;
  Comparison_Function_Pointer compare_function;
};

This organization allows for two BST's, one for ordering by data; the other for ordering by occurrences and using the same structure for the data.

The two BST's represent different indexes for the same data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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