0

In the accepted answer to my question Data Structure For Closest Pair Problem, I do not see why deletion works.

Let's say (x, y) are the closest pair before the delete. If the node to be deleted is either x or y, then we would have to recalculate the closest pair, which would not satisfy the O(log n) requirement. The best solution I currently see is that each time a "new" closest pair occurs during an insertion, we link it to the previous closest pair. That is, instead of storing just the closest pair in the root node, we store a linked list of closest pairs. However, this seems like overkill.

Is there a better way resp. why does the proposed solution work?

EggHead
  • 181
  • 2
  • 10
  • @D.W. It is a follwoup question to that question, as can be seen from their comment on my answer there. This probably should be made explicit in this question. – FrankW Jan 27 '14 at 07:50
  • @FrankW, I understand. From my perspective, this question is already answered over there. Over there we can find a scheme that describes handle how to do deletion, and it does work. It looks like the author just hasn't taken enough time to read and understand that scheme yet. – D.W. Jan 27 '14 at 16:42

1 Answers1

3

The solution I posted on your previous question does work.

To recap, I suggested to maintain in each node:

  • The largest and smallest element in the subtree below this node and
  • the closest pair in that subtree.

On insert and delete, update the information in every node on the path from the inserted/removed leaf to the root and every node affected by a rotation.

Intuitively, this works since the information on the closest pair for each unaffected subtree is stored in the root of that subtree and our update will look at the roots of all maximal unaffected subtrees (and all nodes affected by the upadte). Thus, implicitly, our update will look at the complete tree, in order to find the new closest pair.

In order to show more formally that the update is correct for the root (the only node, where we actually need the annotation), we can show that the following stronger invariant holds:

After each operation the annotations in all the nodes are correct.

This is obvious for operations that don't change the tree. For insert and delete, we distinguish two classes of nodes:

  • If the subtree below the node is unchanged, the annotations that were correct before still are.
  • If the subtree below the node is changed, then the node must be on the path from the inserted/removed leaf to the root or affected by a rotation. In this case we explicitly update the information, so it will be correct.

That the update of each node will produce a correct annotation, can be shown by a simple induction, using the following arguments:

  • (Anchor): The procedure is correct for leaves.
  • (Step): If the information in both children is correct then the described procedure will produce the correct annotation for the parent node.
FrankW
  • 6,589
  • 4
  • 26
  • 42
  • "The solution I posted on your previous question does work." -- so it is a duplicate? – Raphael Jan 27 '14 at 08:57
  • @Raphael I took it as a request for additional explanation. Granted, this is not explicit from the wording of the question at hand. But my gut feeling is that it is more appropriate to change that wording than to incorporate this answer into the previous one. (It would almost double the length, and it does not fit well with the "series of hints" style of that answer.) – FrankW Jan 27 '14 at 09:25
  • By all means, please edit the question into something more suitable resp. fitting. – Raphael Jan 27 '14 at 09:26
  • @Raphael Will do, if the asker doesn't do it themselves. – FrankW Jan 27 '14 at 09:35
  • @Frank It wasn't clear to me why the largest/smallest element needed to be stored in each subtree. The other difficulty I was with "trinode" rebalancing where subtrees were moved to new parents. In this case it wasn't clear how the updates for the closest pair were going to be performed since the "new" parent nodes may not even be on the original path from the root to the inserted/deleted node which means updating on return from the recursive calls will not be possible. In any case, I'm going to take a closer look at those rotations to see if the updates can be performed within O(log). Thanks! – EggHead Jan 27 '14 at 23:17
  • 1
    @FrankW If you think the answers can be merged on the former question and fit together there (the answer does not seem to be AVL-specific), I'd appreciate it if we could get rid of this near-duplicate. – Raphael Jan 28 '14 at 17:31
  • @Raphael Having them as two answers to the original question would probably work, if the introduction to this answer is reworded accordingly. If you want to merge them into a single answer you'd have to put this answer entirely into a spoiler box (maybe two, seperating intuitive idea and proof outline) in order to keep the spirit of the original answer. Feel free to choose the version that fits the site best. – FrankW Jan 28 '14 at 19:55