600.463 Introduction to lgoritms / lgoritms I Lecturer: Micael initz Topic: Splay Trees ate: 9/27/16 8.1 Introduction Today we re going to talk even more about binary searc trees. -trees, red-black trees, VL trees, etc., go to a lot of effort to keep te tree balanced (or approximately balanced), making inserts pretty complicated. Today, we re going to talk about an advanced (and amazing) binary searc tree known as a splay tree, invented by Sleator and Tarjan. Tese are sometimes called self-adjusting binary searc trees, since tey do two tings very differently from oter balanced searc trees: tey don t do anyting to explicitly enforce balance, and tey cange te tree on lookups as well as on inserts. s we ll see, te worst-case performance of splay trees migt not be very good, but tey ave amazing amortized properties: any seuence of operations is actually very ceap. 8.2 Splay Trees Splay trees take a different approac, and provide wat is (in some sense) a weaker bound. We are only going to get O(log n)-amortized time bounds. Some lookup ueries migt actually take a long time (even Ω(n)) to complete. In return, we will get a muc simpler algoritm wit muc less to keep track of, as well as a number of nice properties wic we won t really ave time to talk about. Informally, toug, it turns out tat for splay trees you can prove te Static Optimality Teorem: if you compare te cost of doing m ueries on any fixed tree (suc as a red-black tree or VL tree after we ave finised all inserts), ten te splay tree is (essentially) optimal. Tis is true even if we know te seuence of lookups aead of time, and can tailor our searc tree exactly to te seuence of lookups! Splay trees manage tis despite not knowing te ueries in advance. 8.2.1 Tree rotations Tree rotations are a fundamental building block in most binary searc trees, including splay trees. It s an operation wic (in constant time) allows us to move a node one level iger in te tree, wile still ensuring te searc tree property by rearranging te tree structure appropriately. y repeatedly rotating te same node, we can eventually move it up to te root. Tis turns out to be a useful ability. basic rotation works as in te following figure. Tis is also called rotating on, or Rotate(), since it moves up one level. 1
learly after we do a rotate we still ave a searc tree, and now is one level closer to te root (te parent of pre-rotation is te parent of post-rotation). I aven t drawn it, but clearly tere s an euivalent rotation operation wen w starts out as te rigt cild of. 8.2.2 Splay Tree operations Splay trees are usually described in terms of tree basic operations tat extend simple rotations: te zig operation, te zig-zag operation, and te zig-zig operation. Note tat a basic rotation of a node only considers te parent and cildren. For a splay tree, we also need to consider te grandparent. Te two major operations (zig-zig and zig-zag) move a node up two levels at a time, and ten a zig is a one-level operation tat is necessary in case te eigt is odd. Zig: Te zig operation is te simplest: it is just a simple rotation. We only use it wen tere is no grandparent, i.e. te parent of te node tat we re at is te root. 2
Zig-Zag: Te zig-zag operation is also pretty simple: it s just two rotations (Rotate() followed by Rotate() again). We only do it wen te direction of te edge from te grandparent to te parent is different from te direction of te edge from te parent to te node. So tere are two settings wen we can use a zig-zag: if te node is te rigt cild of te parent and te parent is te left cild of te grandparent, or if te node is te left cild of te parent and te parent is te rigt cild of te grandparent. In tis case, we can essentially do two rotations so tat te node takes te place of te grandparent. x x Zig-Zig: Tis is te operation wic makes splay trees different from just simple rotations. Tere are two cases wic are not covered by zig-zag: if te node is te left cild of te parent and te parent is te left cild of te grandparent, or if te te node is te rigt cild of te parent and te parent is te rigt cild of te grandparent. In tese cases, instead of doing two rotations on, we rotate on and ten rotate on. Tis is called a zig-zig operation, and canges te tree as in te following figure. 3
x x 8.2.3 Splay Tree algoritm Wit tese tree operations in and, it s easy to define te splay tree algoritm. Te combination of tese tree operations is called a splay. Tat is, we say tat we splay a node u if we first ceck wic of te tree situations it is in, and ten apply te appropriate operation (zig, zig-zag, or zig-zig). So instead of rotating a node up to te root, in a splay tree we splay it up to te root. On a Lookup uery, we first walk down te tree as in every binary searc tree to find te key. ut once we ave it, instead of returning it, we first splay it to te root, and ten return it. Tus unlike trees you migt be used to, in a splay tree a Lookup operation actually canges te structure of te tree. n Insert operation is done te same way: we walk down te tree to figure out were to insert it, ten insert it as a new leaf, and ten splay it to te root. 4
8.3 Splay Tree nalysis Note tat a single operation migt take a long time: te tree could get extremely unbalanced if we ave a particularly bad seuence of ueries, in wic case a single operation could take Ω(n) time (see te omework!). Te amazing ting is tat tis cannot appen very often: te amortized complexity of a Lookup or an Insert is only O(log n). We will tink of a single splay operation as aving cost 1. Tis means tat in te end, we ll get amortized bounds on te number of splay operations. Since eac splay operation takes a constant amount of time, tis will give us bounds on te running time (we re ignoring te cost of walking down te tree on a find or insert, since wenever we walk down we splay up te same amount, and so te adding in te walk down would (at most) double te running time). We first need a few definitions. In te following, T is a (splay) tree, u is an arbitrary node in T, and p is te parent of u and g is te grandparent of u. Let s(u) (called te size of u) be te number of nodes in te subtree rooted at u (including u itself). Let r(u) = log(s(u)) (called te rank of u tis is different from te rank we used in te omework). Let Φ(T ) = u T r(u). Tis is te potential function tat we will use. Let s start by noticing some easy properties of ranks. 1. oing a rotate on u affects te ranks of only u and p (te parent of u), and te rank of u after te rotation is eual to te rank of p before te rotation. 2. If two siblings bot ave rank i, ten te parent as rank i + 1. To see tis, let u and v be siblings of rank r wit parent p. Ten by te definition of rank, 2 i s(u) < 2 i+1 and 2 i s(u) < 2 i+1, and ence (wen we include p in s(p)) we get tat 2 i+1 + 1 s(p) < 2 i+2. Tis implies tat r(p) = i + 1. 3. Suppose tat a node u and its parent p bot ave rank i. Ten v, te oter cild of p, as rank less tan i. gain, tis is just by figuring out te sizes: if v also ad rank i, ten we would ave tat s(p) s(u) + s(v) 2 i + 2 i = 2 i+1 and so p would ave rank i + 1. Now let s analyze te cange in potential cause by eac of te tree splay operations. Let r be te rank function before te operation, and let r be te rank function after. Lemma 8.3.1 In a zig operation, Φ r (u) r(u) 3(r (u) r(u)). Proof: Only p and u cange rank, so by definition Φ = r (p) r(p) + r (u) r(u). y our first property of ranks, we know tat r (u) = r(p), so we get tat Φ = r (p) r(u) r (u) r(u). Lemma 8.3.2 In a zig-zag or zig-zig operation, Φ 3(r (u) r(u)) 1 Proof: Note tat only g, p, and u cange ranks, so Φ = r (g) r(g) + r (p) r(p) + r (u) r(u). We analyze te two operations separately. 5
onsider a zig-zag operation. We split into two cases, depending on te initial ranks. First, suppose tat r(g) = r(u) = r (and tus also r(p) = r). y our first property of ranks, we know tat r (u) = r. So by te last two properties of ranks, eiter r (p) or r (g) is strictly less tan r. Tus Φ 1 = 3(r (u) r(u)) 1. In te second case, suppose tat r(g) > r(u). Since r(g) = r (u), we know tat Φ = r (g) + r (p) r(p) r(u). Now by te last two properties of ranks, we know tat r (g) + r (p) 2r (u) 1, and we also know tat r(p) r(u). Hence Φ 2r (u) 1 2r(u) = 2(r (u) r(u)) 1 3(r (u) r(u)) 1. Now consider a zig-zig operation. We again break into te same two cases. In te first case, suppose tat r(g) = r(u) = r (and tus r(p) = r also). Recall tat wen we do a zig-zig, we first rotate p and ten rotate u. fter rotating p, te rank of p and te rank of u are still bot r, but g is now a cild of p and tus its rank must be strictly less tan r. Now wen we rotate u te rank of u becomes r, te rank of p becomes at most r, and te rank of g is still strictly less tan r. Hence Φ 1 = 3(r (u) r(u)) 1. In te second case, suppose tat r(g) > r(u). s always, r (u) and r(g) cancel out and so Φ = r (g) + r (p) r(p) r(u). Now we know tat r (g) + r (p) 2r (u), and also tat r(p) r(u), so we get tat Φ 2r (u) 2r(u) = 2(r (u) r(u)). Since r (u) r(u) 1, we can conclude tat Φ 3(r (u) r(u)) 1. So in every case, Φ 3(r (u) r(u)) 1. We can now prove te main lemma. Lemma 8.3.3 Te amortized cost of splaying a node to te root is O(log n) Proof: We just need to bound te amortized cost of splaying an arbitrary node u up to te root of te tree. Tis will consist of a series of zig-zig or zig-zag operations, and ten possibly one zig operation. Let g 1 be te grandparent of u, let g 2 be te grandparent of g 1, etc., until we get a node g k wic is eiter te root or a cild of te root. We will assume tat g k is a cild of te root, since tat is te more difficult case. So in total we will do k ZZ operations and one zig operation. Let r i be te rank function after we ave done i splay operations, and let Φ i = v T r i(v) be te potential after i splay operations. Ten te total amortized cost is k+1 (1 + Φ i Φ i 1 ) i=1 k (1 + 3(r i (u) r i 1 (u)) 1) + (1 + 3(r k+1 (u) r k (u))) i=1 k+1 3(r i (u) r i 1 (u)) + 1 i=1 = 3(r k+1 (u) r 0 (u)) + 1 3 log n + 1. 6
Now we re essentially done! On a Find or an Insert, te time is essentially (up to a constant factor for te walk down) eual to te cost of splaying a node up to te root, and ence is at most O(log n). Sligtly more formally, we get te following corollary. Teorem 8.3.4 Te running time of doing m operations on a splay tree wit at most n nodes is O(m log n + n log n). Proof: s we saw before wen doing amortized analysis, te actual running time of doing a seuence of operations is eual to teir amortized running time plus te initial potential minus te final potential. Since te final potential is at least 0 and te initial potential is at most n log n, tis means tat te actual running time is O(m log n + n log n). 8.3.1 More results It turns out tat splay trees ave oter, very appealing properties. I m only going to discuss tese informally, but tere s a lot more on te internet. If you re interested, do some googling! Static Optimality: Suppose tat we want a binary searc tree for a specific access seuence. Ten we clearly will use our knowledge of tis seuence to make a better (fixed) tree we can put te most accessed elements towards te top of te tree, for example. Informally, as long as we do at least n Finds, it turns out tat splay trees are self-optimizing: tey perform at least as well (up to a constant factor) as te best fixed tree. Working Set: Suppose tat we want to access item x, and let k(x) be te number of distinct items tat we ave accessed since te last time we accessed x. Ten te amortized time to access x is only O(1 + log(k(x))). So if we ave a small working set (number of items tat we access regularly), ten te cost of eac access is actually less tan O(log n). ynamic Optimality onjecture: Tis is only a conjecture at tis point, not a teorem. Te conjecture is tat splay trees are, up to a constant factor, as good as any oter dynamic tree on every single access seuence. Here by a dynamic tree we mean a tree tat is allowed to cange troug rotations. So for any access seuence, not only are splay trees as good as te best fixed tree, te conjecture is tat tey are as good as te best dynamic tree. 7