# HG changeset patch # User Balazs Dezso # Date 1229814782 -3600 # Node ID 561be42c4b9935bf3e30a922b8945b2397286a8f # Parent b0f74ca2e3ac2d7e7a63795d086d499323da8f0e Bug fix in heap unionfind (ticket #197) The minimum item in the unionfind tree might become inconsistent when the split operation merges two subtrees which have equal keys. The current changeset fix the problem. It also fix a wrong index. diff -r b0f74ca2e3ac -r 561be42c4b99 lemon/unionfind.h --- a/lemon/unionfind.h Fri Dec 12 21:37:22 2008 +0100 +++ b/lemon/unionfind.h Sun Dec 21 00:13:02 2008 +0100 @@ -1177,9 +1177,9 @@ int pd = nodes[jd].parent; if (nodes[nodes[jd].next].size < cmax) { pushLeft(nodes[jd].next, nodes[jd].left); - if (less(nodes[jd].left, nodes[jd].next)) { - nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio; - nodes[nodes[jd].next].item = nodes[nodes[jd].left].item; + if (nodes[jd].item == nodes[pd].item) { + nodes[nodes[jd].next].prio = nodes[jd].prio; + nodes[nodes[jd].next].item = nodes[jd].item; } popLeft(pd); deleteNode(jd); @@ -1188,9 +1188,10 @@ int ld = nodes[nodes[jd].next].left; popLeft(nodes[jd].next); pushRight(jd, ld); - if (less(ld, nodes[jd].left)) { + if (less(ld, nodes[jd].left) || + nodes[ld].item == nodes[pd].item) { nodes[jd].item = nodes[ld].item; - nodes[jd].prio = nodes[jd].prio; + nodes[jd].prio = nodes[ld].prio; } if (nodes[nodes[jd].next].item == nodes[ld].item) { setPrio(nodes[jd].next); @@ -1219,9 +1220,9 @@ int pd = nodes[jd].parent; if (nodes[nodes[jd].prev].size < cmax) { pushRight(nodes[jd].prev, nodes[jd].right); - if (less(nodes[jd].right, nodes[jd].prev)) { - nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio; - nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item; + if (nodes[jd].item == nodes[pd].item) { + nodes[nodes[jd].prev].prio = nodes[jd].prio; + nodes[nodes[jd].prev].item = nodes[jd].item; } popRight(pd); deleteNode(jd); @@ -1230,9 +1231,10 @@ int ld = nodes[nodes[jd].prev].right; popRight(nodes[jd].prev); pushLeft(jd, ld); - if (less(ld, nodes[jd].right)) { + if (less(ld, nodes[jd].right) || + nodes[ld].item == nodes[pd].item) { nodes[jd].item = nodes[ld].item; - nodes[jd].prio = nodes[jd].prio; + nodes[jd].prio = nodes[ld].prio; } if (nodes[nodes[jd].prev].item == nodes[ld].item) { setPrio(nodes[jd].prev); @@ -1400,7 +1402,14 @@ } push(new_id, right_id); pushRight(new_id, ~(classes[r].parent)); - setPrio(new_id); + + if (less(~classes[r].parent, right_id)) { + nodes[new_id].item = nodes[~classes[r].parent].item; + nodes[new_id].prio = nodes[~classes[r].parent].prio; + } else { + nodes[new_id].item = nodes[right_id].item; + nodes[new_id].prio = nodes[right_id].prio; + } id = nodes[id].parent; classes[r].parent = ~new_id; @@ -1440,7 +1449,14 @@ } push(new_id, left_id); pushLeft(new_id, ~(classes[l].parent)); - setPrio(new_id); + + if (less(~classes[l].parent, left_id)) { + nodes[new_id].item = nodes[~classes[l].parent].item; + nodes[new_id].prio = nodes[~classes[l].parent].prio; + } else { + nodes[new_id].item = nodes[left_id].item; + nodes[new_id].prio = nodes[left_id].prio; + } id = nodes[id].parent; classes[l].parent = ~new_id;