fbpx
Wikipedia

Link/cut tree


A link/cut tree is a data structure for representing a forest, a set of rooted trees, and offers the following operations:

  • Add a tree consisting of a single node to the forest.
  • Given a node in one of the trees, disconnect it (and its subtree) from the tree of which it is part.
  • Attach a node to another node as its child.
  • Given a node, find the root of the tree to which it belongs. By doing this operation on two distinct nodes, one can check whether they belong to the same tree.
Link/cut tree
TypeTree
Invented1982
Invented by
Time complexity in big O notation
AverageWorst case
Link O(log n) amortized O(log n)
Cut O(log n) amortized O(log n)
Path O(log n) amortized O(log n)
FindRoot O(log n) amortized O(log n)

The represented forest may consist of very deep trees, so if we represent the forest as a plain collection of parent pointer trees, it might take us a long time to find the root of a given node. However, if we represent each tree in the forest as a link/cut tree, we can find which tree an element belongs to in O(log(n)) amortized time. Moreover, we can quickly adjust the collection of link/cut trees to changes in the represented forest. In particular, we can adjust it to merge (link) and split (cut) in O(log(n)) amortized time.

Link/cut trees divide each tree in the represented forest into vertex-disjoint paths, where each path is represented by an auxiliary data structure (often splay trees, though the original paper predates splay trees and thus uses biased binary search trees). The nodes in the auxiliary data structure are ordered by their depth in the corresponding represented tree. In one variation, Naive Partitioning, the paths are determined by the most recently accessed paths and nodes, similar to Tango Trees. In Partitioning by Size paths are determined by the heaviest child (child with the most children) of the given node. This gives a more complicated structure, but reduces the cost of the operations from amortized O(log n) to worst case O(log n). It has uses in solving a variety of network flow problems and to jive data sets.

In the original publication, Sleator and Tarjan referred to link/cut trees as "dynamic trees", or "dynamic dyno trees".

Structure edit

We take a tree where each node has an arbitrary degree of unordered nodes and split it into paths. We call this the represented tree. These paths are represented internally by auxiliary trees (here we will use splay trees), where the nodes from left to right represent the path from root to the last node on the path. Nodes that are connected in the represented tree that are not on the same preferred path (and therefore not in the same auxiliary tree) are connected via a path-parent pointer. This pointer is stored in the root of the auxiliary tree representing the path.

 
Demonstrating how nodes are stored by depth in the link-cut tree

Preferred paths edit

When an access to a node v is made on the represented tree, the path that is taken becomes the preferred path. The preferred child of a node is the last child that was on the access path, or null if the last access was to v or if no accesses were made to this particular branch of the tree. A preferred edge is the edge that connects the preferred child to v.

In an alternate version, preferred paths are determined by the heaviest child.

 
Showing how a link cut tree transforms preferred paths into a forest of trees.

Operations edit

The operations we are interested in are FindRoot(Node v), Cut(Node v), Link(Node v, Node w), and Path(Node v). Every operation is implemented using the Access(Node v) subroutine. When we access a vertex v, the preferred path of the represented tree is changed to a path from the root R of the represented tree to the node v. If a node on the access path previously had a preferred child u, and the path now goes to child w, the old preferred edge is deleted (changed to a path-parent pointer), and the new path now goes through w.

Access edit

After performing an access to node v, it will no longer have any preferred children, and will be at the end of the path. Since nodes in the auxiliary tree are keyed by depth, this means that any nodes to the right of v in the auxiliary tree must be disconnected. In a splay tree this is a relatively simple procedure; we splay at v, which brings v to the root of the auxiliary tree. We then disconnect the right subtree of v, which is every node that came below it on the previous preferred path. The root of the disconnected tree will have a path-parent pointer, which we point to v.

We now walk up the represented tree to the root R, breaking and resetting the preferred path where necessary. To do this we follow the path-parent pointer from v (since v is now the root, we have direct access to the path-parent pointer). If the path that v is on already contains the root R (since the nodes are keyed by depth, it would be the left most node in the auxiliary tree), the path-parent pointer will be null, and we are done the access. Otherwise we follow the pointer to some node on another path w. We want to break the old preferred path of w and reconnect it to the path v is on. To do this we splay at w, and disconnect its right subtree, setting its path-parent pointer to w. Since all nodes are keyed by depth, and every node in the path of v is deeper than every node in the path of w (since they are children of w in the represented tree), we simply connect the tree of v as the right child of w. We splay at v again, which, since v is a child of the root w, simply rotates v to root. We repeat this entire process until the path-parent pointer of v is null, at which point it is on the same preferred path as the root of the represented tree R.

 
During an access old preferred paths are broken and replaced with path-parent pointers, while the accessed node is splayed to the root of the tree

FindRoot edit

FindRoot refers to finding the root of the represented tree that contains the node v. Since the access subroutine puts v on the preferred path, we first execute an access. Now the node v is on the same preferred path, and thus the same auxiliary tree as the root R. Since the auxiliary trees are keyed by depth, the root R will be the leftmost node of the auxiliary tree. So we simply choose the left child of v recursively until we can go no further, and this node is the root R. The root may be linearly deep (which is worst case for a splay tree), we therefore splay it so that the next access will be quick.

Cut edit

Here we would like to cut the represented tree at node v. First we access v. This puts all the elements lower than v in the represented tree as the right child of v in the auxiliary tree. All the elements now in the left subtree of v are the nodes higher than v in the represented tree. We therefore disconnect the left child of v (which still maintains an attachment to the original represented tree through its path-parent pointer). Now v is the root of a represented tree. Accessing v breaks the preferred path below v as well, but that subtree maintains its connection to v through its path-parent pointer.

Link edit

If v is a tree root and w is a vertex in another tree, link the trees containing v and w by adding the edge(v, w), making w the parent of v. To do this we access both v and w in their respective trees, and make w the left child of v. Since v is the root, and nodes are keyed by depth in the auxiliary tree, accessing v means that v will have no left child in the auxiliary tree (since as root it is the minimum depth). Adding w as a left child effectively makes it the parent of v in the represented tree.

Path edit

For this operation we wish to do some aggregate function over all the nodes (or edges) on the path from root R to node v (such as "sum" or "min" or "max" or "increase", etc.). To do this we access v, which gives us an auxiliary tree with all the nodes on the path from root R to node v. The data structure can be augmented with data we wish to retrieve, such as min or max values, or the sum of the costs in the subtree, which can then be returned from a given path in constant time.

Pseudocode of operations edit

Switch-Preferred-Child(x, y):  if (right(x) is not null)  path-parent(right(x)) = x  right(x) = y  if (y is not null)  parent(y) = x 
Access(v):  splay(v)  Switch-Preferred-Child(v, null)  if (path-parent(v) is not null)  w = path-parent(v)  splay(w)  Switch-Preferred-Child(w, v)  Access(v) 
Link(v, w):  Access(v)  Access(w)  left(v) = w  parent(w) = v 
Cut(v):  Access(v)  if (left(v) is not null)  path-parent(left(v)) = path-parent(v)  left(v) = null  path-parent(v) = null 

Analysis edit

Cut and link have O(1) cost, plus that of the access. FindRoot has an O(log n) amortized upper bound, plus the cost of the access. The data structure can be augmented with additional information (such as the min or max valued node in its subtrees, or the sum), depending on the implementation. Thus Path can return this information in constant time plus the access bound.

So it remains to bound the access to find our running time.

Access makes use of splaying, which we know has an O(log n) amortized upper bound. So the remaining analysis deals with the number of times we need to splay. This is equal to the number of preferred child changes (the number of edges changed in the preferred path) as we traverse up the tree.

We bound access by using a technique called Heavy-Light Decomposition.

Heavy-light decomposition edit

This technique calls an edge heavy or light depending on the number of nodes in the subtree.   represents the number of nodes in the subtree of v in the represented tree. An edge is called heavy if size(v) > 12 size(parent(v)). Thus we can see that each node can have at most 1 heavy edge. An edge that is not a heavy edge is referred to as a light edge.

The light-depth refers to the number of light edges on a given path from root to vertex v. Light-depth ≤ lg n because each time we traverse a light-edge we decrease the number of nodes by at least a factor of 2 (since it can have at most half the nodes of the parent).

So a given edge in the represented tree can be any of four possibilities: heavy-preferred, heavy-unpreferred, light-preferred or light-unpreferred.

First we prove an   upper bound.

O(log 2 n) upper bound edit

The splay operation of the access gives us log n, so we need to bound the number of accesses to log n to prove the O(log 2 n) upper bound.

Every change of preferred edge results in a new preferred edge being formed. So we count the number of preferred edges formed. Since there are at most log n edges that are light on any given path, there are at most log n light edges changing to preferred.

The number of heavy edges becoming preferred can be   for any given operation, but it is   amortized. Over a series of executions we can have n-1 heavy edges become preferred (as there are at most n-1 heavy edges total in the represented tree), but from then on the number of heavy edges that become preferred is equal to the number of heavy edges that became unpreferred on a previous step. For every heavy edge that becomes unpreferred a light edge must become preferred. We have seen already that the number of light edges that can become preferred is at most log n. So the number of heavy edges that become preferred for m operations is  . Over enough operations ( ) this averages to  .

Improving to O(log n) upper bound edit

We have bound the number of preferred child changes at  , so if we can show that each preferred child change has cost O(1) amortized we can bound the access operation at  . This is done using the potential method.

Let s(v) be the number of nodes under v in the tree of auxiliary trees. Then the potential function  . We know that the amortized cost of splaying is bounded by:

 

We know that after splaying, v is the child of its path-parent node w. So we know that:

 

We use this inequality and the amortized cost of access to achieve a telescoping sum that is bounded by:

 

where R is the root of the represented tree, and we know the number of preferred child changes is  . s(R) = n, so we have   amortized.

Application edit

Link/cut trees can be used to solve the dynamic connectivity problem for acyclic graphs. Given two nodes x and y, they are connected if and only if FindRoot(x) = FindRoot(y). Another data structure that can be used for the same purpose is Euler tour tree.

In solving the maximum flow problem, link/cut trees can be used to improve the running time of Dinic's algorithm from   to  .

See also edit

Further reading edit

  • Sleator, D. D.; Tarjan, R. E. (1983). "A Data Structure for Dynamic Trees". Proceedings of the thirteenth annual ACM symposium on Theory of computing - STOC '81 (PDF). p. 114. doi:10.1145/800076.802464.
  • Sleator, D. D.; Tarjan, R. E. (1985). "Self-Adjusting Binary Search Trees" (PDF). Journal of the ACM. 32 (3): 652. doi:10.1145/3828.3835.
  • Goldberg, A. V.; Tarjan, R. E. (1989). "Finding minimum-cost circulations by canceling negative cycles". Journal of the ACM. 36 (4): 873. doi:10.1145/76359.76368. – Application to min-cost circulation
  • Link-Cut trees in: lecture notes in advanced data structures, Spring 2012, lecture 19. Prof. Erik Demaine, Scribes: Scribes: Justin Holmgren (2012), Jing Jian (2012), Maksim Stepanenko (2012), Mashhood Ishaque (2007).
  • https://jeffe.cs.illinois.edu/teaching/datastructures/2006/notes/07-linkcut.pdf

link, tree, this, article, includes, list, references, related, reading, external, links, sources, remain, unclear, because, lacks, inline, citations, please, help, improve, this, article, introducing, more, precise, citations, october, 2015, learn, when, remo. This article includes a list of references related reading or external links but its sources remain unclear because it lacks inline citations Please help improve this article by introducing more precise citations October 2015 Learn how and when to remove this message A link cut tree is a data structure for representing a forest a set of rooted trees and offers the following operations Add a tree consisting of a single node to the forest Given a node in one of the trees disconnect it and its subtree from the tree of which it is part Attach a node to another node as its child Given a node find the root of the tree to which it belongs By doing this operation on two distinct nodes one can check whether they belong to the same tree Link cut treeTypeTreeInvented1982Invented byDaniel Dominic SleatorRobert Endre TarjanTime complexity in big O notationAverageWorst caseLinkO log n amortized O log n CutO log n amortized O log n PathO log n amortized O log n FindRootO log n amortized O log n The represented forest may consist of very deep trees so if we represent the forest as a plain collection of parent pointer trees it might take us a long time to find the root of a given node However if we represent each tree in the forest as a link cut tree we can find which tree an element belongs to in O log n amortized time Moreover we can quickly adjust the collection of link cut trees to changes in the represented forest In particular we can adjust it to merge link and split cut in O log n amortized time Link cut trees divide each tree in the represented forest into vertex disjoint paths where each path is represented by an auxiliary data structure often splay trees though the original paper predates splay trees and thus uses biased binary search trees The nodes in the auxiliary data structure are ordered by their depth in the corresponding represented tree In one variation Naive Partitioning the paths are determined by the most recently accessed paths and nodes similar to Tango Trees In Partitioning by Size paths are determined by the heaviest child child with the most children of the given node This gives a more complicated structure but reduces the cost of the operations from amortized O log n to worst case O log n It has uses in solving a variety of network flow problems and to jive data sets In the original publication Sleator and Tarjan referred to link cut trees as dynamic trees or dynamic dyno trees Contents 1 Structure 1 1 Preferred paths 2 Operations 2 1 Access 2 2 FindRoot 2 3 Cut 2 4 Link 2 5 Path 3 Pseudocode of operations 4 Analysis 4 1 Heavy light decomposition 4 1 1 O log 2 n upper bound 4 1 2 Improving to O log n upper bound 5 Application 6 See also 7 Further readingStructure editWe take a tree where each node has an arbitrary degree of unordered nodes and split it into paths We call this the represented tree These paths are represented internally by auxiliary trees here we will use splay trees where the nodes from left to right represent the path from root to the last node on the path Nodes that are connected in the represented tree that are not on the same preferred path and therefore not in the same auxiliary tree are connected via a path parent pointer This pointer is stored in the root of the auxiliary tree representing the path nbsp Demonstrating how nodes are stored by depth in the link cut tree Preferred paths edit When an access to a node v is made on the represented tree the path that is taken becomes the preferred path The preferred child of a node is the last child that was on the access path or null if the last access was to v or if no accesses were made to this particular branch of the tree A preferred edge is the edge that connects the preferred child to v In an alternate version preferred paths are determined by the heaviest child nbsp Showing how a link cut tree transforms preferred paths into a forest of trees Operations editThe operations we are interested in are FindRoot Node v Cut Node v Link Node v Node w and Path Node v Every operation is implemented using the Access Node v subroutine When we access a vertex v the preferred path of the represented tree is changed to a path from the root R of the represented tree to the node v If a node on the access path previously had a preferred child u and the path now goes to child w the old preferred edge is deleted changed to a path parent pointer and the new path now goes through w Access edit After performing an access to node v it will no longer have any preferred children and will be at the end of the path Since nodes in the auxiliary tree are keyed by depth this means that any nodes to the right of v in the auxiliary tree must be disconnected In a splay tree this is a relatively simple procedure we splay at v which brings v to the root of the auxiliary tree We then disconnect the right subtree of v which is every node that came below it on the previous preferred path The root of the disconnected tree will have a path parent pointer which we point to v We now walk up the represented tree to the root R breaking and resetting the preferred path where necessary To do this we follow the path parent pointer from v since v is now the root we have direct access to the path parent pointer If the path that v is on already contains the root R since the nodes are keyed by depth it would be the left most node in the auxiliary tree the path parent pointer will be null and we are done the access Otherwise we follow the pointer to some node on another path w We want to break the old preferred path of w and reconnect it to the path v is on To do this we splay at w and disconnect its right subtree setting its path parent pointer to w Since all nodes are keyed by depth and every node in the path of v is deeper than every node in the path of w since they are children of w in the represented tree we simply connect the tree of v as the right child of w We splay at v again which since v is a child of the root w simply rotates v to root We repeat this entire process until the path parent pointer of v is null at which point it is on the same preferred path as the root of the represented tree R nbsp During an access old preferred paths are broken and replaced with path parent pointers while the accessed node is splayed to the root of the tree FindRoot edit FindRoot refers to finding the root of the represented tree that contains the node v Since the access subroutine puts v on the preferred path we first execute an access Now the node v is on the same preferred path and thus the same auxiliary tree as the root R Since the auxiliary trees are keyed by depth the root R will be the leftmost node of the auxiliary tree So we simply choose the left child of v recursively until we can go no further and this node is the root R The root may be linearly deep which is worst case for a splay tree we therefore splay it so that the next access will be quick Cut edit Here we would like to cut the represented tree at node v First we access v This puts all the elements lower than v in the represented tree as the right child of v in the auxiliary tree All the elements now in the left subtree of v are the nodes higher than v in the represented tree We therefore disconnect the left child of v which still maintains an attachment to the original represented tree through its path parent pointer Now v is the root of a represented tree Accessing v breaks the preferred path below v as well but that subtree maintains its connection to v through its path parent pointer Link edit If v is a tree root and w is a vertex in another tree link the trees containing v and w by adding the edge v w making w the parent of v To do this we access both v and w in their respective trees and make w the left child of v Since v is the root and nodes are keyed by depth in the auxiliary tree accessing v means that v will have no left child in the auxiliary tree since as root it is the minimum depth Adding w as a left child effectively makes it the parent of v in the represented tree Path edit For this operation we wish to do some aggregate function over all the nodes or edges on the path from root R to node v such as sum or min or max or increase etc To do this we access v which gives us an auxiliary tree with all the nodes on the path from root R to node v The data structure can be augmented with data we wish to retrieve such as min or max values or the sum of the costs in the subtree which can then be returned from a given path in constant time Pseudocode of operations editSwitch Preferred Child x y if right x is not null path parent right x x right x y if y is not null parent y x Access v splay v Switch Preferred Child v null if path parent v is not null w path parent v splay w Switch Preferred Child w v Access v Link v w Access v Access w left v w parent w v Cut v Access v if left v is not null path parent left v path parent v left v null path parent v nullAnalysis editCut and link have O 1 cost plus that of the access FindRoot has an O log n amortized upper bound plus the cost of the access The data structure can be augmented with additional information such as the min or max valued node in its subtrees or the sum depending on the implementation Thus Path can return this information in constant time plus the access bound So it remains to bound the access to find our running time Access makes use of splaying which we know has an O log n amortized upper bound So the remaining analysis deals with the number of times we need to splay This is equal to the number of preferred child changes the number of edges changed in the preferred path as we traverse up the tree We bound access by using a technique called Heavy Light Decomposition Heavy light decomposition edit Main article Heavy path decomposition This technique calls an edge heavy or light depending on the number of nodes in the subtree S i z e v displaystyle Size v nbsp represents the number of nodes in the subtree of v in the represented tree An edge is called heavy if size v gt 1 2 size parent v Thus we can see that each node can have at most 1 heavy edge An edge that is not a heavy edge is referred to as a light edge The light depth refers to the number of light edges on a given path from root to vertex v Light depth lg n because each time we traverse a light edge we decrease the number of nodes by at least a factor of 2 since it can have at most half the nodes of the parent So a given edge in the represented tree can be any of four possibilities heavy preferred heavy unpreferred light preferred or light unpreferred First we prove an O log 2 n displaystyle O log 2 n nbsp upper bound O log 2 n upper bound edit The splay operation of the access gives us log n so we need to bound the number of accesses to log n to prove the O log 2 n upper bound Every change of preferred edge results in a new preferred edge being formed So we count the number of preferred edges formed Since there are at most log n edges that are light on any given path there are at most log n light edges changing to preferred The number of heavy edges becoming preferred can be O n displaystyle O n nbsp for any given operation but it is O log n displaystyle O log n nbsp amortized Over a series of executions we can have n 1 heavy edges become preferred as there are at most n 1 heavy edges total in the represented tree but from then on the number of heavy edges that become preferred is equal to the number of heavy edges that became unpreferred on a previous step For every heavy edge that becomes unpreferred a light edge must become preferred We have seen already that the number of light edges that can become preferred is at most log n So the number of heavy edges that become preferred for m operations is m log n n 1 displaystyle m log n n 1 nbsp Over enough operations m gt n 1 displaystyle m gt n 1 nbsp this averages to O log n displaystyle O log n nbsp Improving to O log n upper bound edit We have bound the number of preferred child changes at O log n displaystyle O log n nbsp so if we can show that each preferred child change has cost O 1 amortized we can bound the access operation at O log n displaystyle O log n nbsp This is done using the potential method Let s v be the number of nodes under v in the tree of auxiliary trees Then the potential function F v log s v displaystyle Phi sum v log s v nbsp We know that the amortized cost of splaying is bounded by c o s t s p l a y v 3 log s r o o t v log s v 1 displaystyle cost splay v leq 3 left log s root v log s v right 1 nbsp We know that after splaying v is the child of its path parent node w So we know that s v s w displaystyle s v leq s w nbsp We use this inequality and the amortized cost of access to achieve a telescoping sum that is bounded by 3 log s R log s v O number of preferred child changes displaystyle 3 left log s R log s v right O text number of preferred child changes nbsp where R is the root of the represented tree and we know the number of preferred child changes is O log n displaystyle O log n nbsp s R n so we have O log n displaystyle O log n nbsp amortized Application editLink cut trees can be used to solve the dynamic connectivity problem for acyclic graphs Given two nodes x and y they are connected if and only if FindRoot x FindRoot y Another data structure that can be used for the same purpose is Euler tour tree In solving the maximum flow problem link cut trees can be used to improve the running time of Dinic s algorithm from O V 2 E displaystyle O V 2 E nbsp to O V E log V displaystyle O VE log V nbsp See also editSplay tree Potential method Top treeFurther reading editSleator D D Tarjan R E 1983 A Data Structure for Dynamic Trees Proceedings of the thirteenth annual ACM symposium on Theory of computing STOC 81 PDF p 114 doi 10 1145 800076 802464 Sleator D D Tarjan R E 1985 Self Adjusting Binary Search Trees PDF Journal of the ACM 32 3 652 doi 10 1145 3828 3835 Goldberg A V Tarjan R E 1989 Finding minimum cost circulations by canceling negative cycles Journal of the ACM 36 4 873 doi 10 1145 76359 76368 Application to min cost circulation Link Cut trees in lecture notes in advanced data structures Spring 2012 lecture 19 Prof Erik Demaine Scribes Scribes Justin Holmgren 2012 Jing Jian 2012 Maksim Stepanenko 2012 Mashhood Ishaque 2007 https jeffe cs illinois edu teaching datastructures 2006 notes 07 linkcut pdf Retrieved from https en wikipedia org w index php title Link cut tree amp oldid 1155837096, wikipedia, wiki, book, books, library,

article

, read, download, free, free download, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, picture, music, song, movie, book, game, games.