Skip to content

Instantly share code, notes, and snippets.

Created December 26, 2012 21:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/2df01576cd9843d34b10 to your computer and use it in GitHub Desktop.
Save anonymous/2df01576cd9843d34b10 to your computer and use it in GitHub Desktop.
(defn find-root [graph ^long node-id]
(let [^Node node (get graph node-id)
parent-id (.parent-id node)]
(if (= parent-id node-id)
[graph node-id]
(let [[graph ^long root-id] (find-root graph parent-id)]
[(update-in graph [node-id] set-parent root-id)
root-id]))))
@jordanlewis
Copy link

Say there's a path in your graph that looks like this: 1->2->3->4->4

You look up 2. The path starting from 2 turns into this: 2->4->4
But, since you didn't update 1, there's still a path 1->2->3->4->4 that has a different '2' node than the new '2' node you created with path compression, right?

My intuition says that this ends up hurting your complexity in some way. But I'm not entirely sure.

@amalloy
Copy link

amalloy commented Dec 26, 2012

@jordanlewis No, because nodes don't point at other nodes in memory. They store an identifier number, and when I want to follow a parent link, I look that number up in the updated forest.

@jordanlewis
Copy link

OK, so the reason it hurts your time complexity is that the path compression only helps the nodes between the one you look up and the root! Usually, since the rest of the path before the node you look up continues to point at the node that gets compressed, it'll be quicker to find the root next time for the whole path, not just the nodes between the looked-up node and the root. To me it's a pretty clear worsening of the time guarantees.

@jordanlewis
Copy link

Oh, that makes sense. Nevermind!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment