# Mini Lecture: Running Time of Merging

### COSC 311 Algorithms, Fall 2022

$\def\compare{ {\mathrm{compare}} } \def\swap{ {\mathrm{swap}} } \def\sort{ {\mathrm{sort}} } \def\insert{ {\mathrm{insert}} } \def\true{ {\mathrm{true}} } \def\false{ {\mathrm{false}} } \def\BubbleSort{ {\mathrm{BubbleSort}} } \def\SelectionSort{ {\mathrm{SelectionSort}} } \def\Merge{ {\mathrm{Merge}} } \def\MergeSort{ {\mathrm{MergeSort}} } \def\QuickSort{ {\mathrm{QuickSort}} } \def\Split{ {\mathrm{Split}} } \def\Multiply{ {\mathrm{Multiply}} } \def\Add{ {\mathrm{Add}} } \def\cur{ {\mathrm{cur}} } \def\gets{ {\leftarrow} }$

## Last Time

Kruskal’s Algorithm for MSTs:

• iterate over all edges in ascending order of weight
• if an edge connects two previously un-connected components, add it to MST

## Kruskal’s Algorithm

  Kruskal(V, E, w):
C <- collection of components
initially, each vertex is own component
F <- empty collection
# iterate in order of increasing weight
for each edge e = (u, v) in E
if u and v are in different components then
add (u, v) to F
merge components containing u and v
endif
endfor
return F


## Maintaining Components

Associate a leader with each component

• leader is a vertex in the component
• maintain array of leaders
• leader[i] = v means that v is leader of i’s component
• for each leader v, maintain a (linked) list of elements in v’s component
• list also stores size of the component

## Merging Components

To merge components with leaders $u$ and $v$

1. Choose larger component’s leader to be new leader ($u$)
2. Iterate over each vertex $x$ in $v$’s list and
• add $x$ to $u$’s list
• update leader[x] <- u

Running time: $O(\text{size of smaller component})$

• time per element is $O(1)$

## Simplistic Analysis

  Kruskal(V, E, w):
C <- collection of components
initially, each vertex is own component
F <- empty collection
# iterate in order of increasing weight
for each edge e = (u, v) in E
if u and v are in different components then
add (u, v) to F
merge components containing u and v
endif
endfor
return F


## Fewer Merges

  Kruskal(V, E, w):
C <- collection of components
initially, each vertex is own component
F <- empty collection
# iterate in order of increasing weight
for each edge e = (u, v) in E
if u and v are in different components then
add (u, v) to F
merge components containing u and v
endif
endfor
return F


## Amortized Cost of Merges

Consider the number of times each element’s leader is updated

Claim. If $x$ is relabeled $k$ times, then $x$’s component has size at least $2^k$.

Consequence 1. If $x$’s component has size $\ell$, then $x$ was relabeled at most $\log \ell$ times.

Consequence 2. Running time of all merge operations in Kruskal is $O(n \log n)$

## Conclusion

Theorem. Kruskal’s algorithm can be implemented to run in time $O(m \log n)$ in graphs with $n$ vertices and $m$ edges.

• running time dominated by getting edges in ascending weight order

Remark. More efficient data structures for merging sets exist

• “Union-find” ADT, “disjoint-set forest” data structure
• time to perform merges is $O(n \alpha(n))$
• $\alpha(n)$ is “inverse Ackerman function”
• $\alpha(n)$ grows so slowly, it is practically constant