rslt ← {larg} (op ##.splay) rarg ⍝ Splay trees. T∆ ← T ∪ splay (key val) ⍝ tree ⍺ with key=val ⍵. T∆ ← T ~ splay key ⍝ tree ⍺ without key ⍵. T∆ ← T ⍎ splay key ⍝ value for key ⍵ in tree ⍺. dep ← T ≡ splay key ⍝ depth of key ⍵ in tree ⍺. fmt ← ⍕ splay T ⍝ format of tree ⍵. vec ← ∊ splay T ⍝ enlist of tree ⍵. chk ← ? splay T ⍝ stats for tree ⍵: ok size mean_depth height. See →BST← A splay tree is a self-balancing binary search tree; each time a node is access- ed, it is rotated nearer to the root. This mean that frequently accessed nodes wind up with shorter search paths. Unlike →avl← and →redblack← trees, splay trees are not maintained in a state of reasonable balance. Instead, nodes with frequently accessed keys _tend_ to migrate towards the root, which _tends_ to give them shorter access times. The performance of a splay tree may not be as optimal as one of its more complex relatives, but its implementation is considerably simpler. Node Access ----------- In the following, node [A] is accessed. There are three cases, × two left-right mirrow-image orientations. [0] Node [A] is the root node: no change. [1] Node [A] is the left (right) child of the root. [2] Node [A] is the left (right) child of a left (right) child. ¯¯¯¯ ¯¯¯¯ [3] Node [A] is the right (left) child of a left (right) child. ¯¯¯¯¯ ¯¯¯¯ Cases [1 2 3] are summarised in the following diagram: <--- m i r r o r i m a g e s ---> ┌──────────────────────┬────────────────────────┐ [1] │ B [A] │ B [A] │ │ / \ → / \ │ / \ → / \ │ │ [A] r p B │ r [A] B p │ │ / \ / \ │ / \ / \ │ │ p q q r │ q p r q │ ├──────────────────────┼────────────────────────┤ [2] │ C [A] │ C [A] │ │ / \ → / \ │ / \ → / \ │ │ B s p B │ s B B p │ │ / \ / \ │ / \ / \ │ │ [A] r q C │ r [A] C q │ │ / \ / \ │ / \ / \ │ │p q r s │ q p s r │ ├──────────────────────┼────────────────────────┤ [3] │ C [A] │ C [A] │ │ / \ → / \ │ / \ → / \ │ │ B s / \ │ s B / \ │ │ / \ B C │ / \ C B │ │p [A] / \ / \ │ [A] p / \ / \ │ │ / \ p q r s │ / \ s r q p│ │ q r │ r q │ └──────────────────────┴────────────────────────┘ Node removal ------------ [splay] uses the "quicker" method of node removal. See →BST←. Technical notes --------------- The tree is implemented as the pair-of-pairs: (key val) (lft rgt) key: node key val: node value lft: left subtree or 0 rgt: right subtree or 0 The two double rotations are coded by applying function [rot] twice. If speed is critical, we could code them directly as follows: rotrr←{ ⍝ double ⍵-⍵-wise rotion of tree ⍺. C(BAr s)←⍵ wise\⍺ ⍝ C A B(Apq r)←⍵ wise\BAr ⍝ / \ → / \ A(p q)←⍵ wise\Apq ⍝ B s p B ⍝ / \ / \ Crs←⍵ wise\C(r s) ⍝ A r q C BqC←⍵ wise\B(q Crs) ⍝ / \ / \ ⍵ wise\A(p BqC) ⍝ p q r s } rotrl←{ ⍝ double ⍵-¯⍵-rotation of tree ⍺. C(BpA s)←⍵ wise\⍺ ⍝ C A B(p Aqr)←⍵ wise\BpA ⍝ / \ → / \ A(q r)←⍵ wise\Aqr ⍝ B s / \ ⍝ / \ B C Bpq←⍵ wise\B(p q) ⍝ p A / \ / \ Crs←⍵ wise\C(r s) ⍝ / \ p q r s ⍵ wise\A(Bpq Crs) ⍝ q r } Notice that function ⍵-wise is applied under scan (\), which means that it aff- ects only the second item of the node pair (key val)(lft rgt). References ---------- http://en.wikipedia.org/wiki/Splay_tree Examples -------- ⍝ key=value pairs: pairs ← ('one'1) ('two'2) ('three'3) ('four'4) ('five'5) ('six'6) ('seven'7) tt ← 0 ∪splay foldl pairs ⍝ insert key=val pairs into a splay tree. display ⍕splay tt ⍝ show resulting tree. ┌→────────────────────────────────┐ ↓ ┌five=5 │ │ ┌four=4┘ │ │one=1┤ │ │ │ ┌seven=7│ │ │ ┌six=6┘ │ │ │ ┌three=3┘ │ │ └two=2┘ │ └─────────────────────────────────┘ 'seven' ≡splay tt ⍝ depth of key 'seven'. 5 val tt ← 'seven' ⍎splay tt ⍝ first access of key 'seven', display ⍕splay tt ⍝ moves it towards the root. ┌→────────────────────────────────┐ ↓ ┌five=5 │ │ ┌four=4┘ │ │one=1┤ │ │ │ ┌seven=7┐ │ │ │ │ └six=6┐ │ │ │ │ └three=3│ │ └two=2┘ │ └─────────────────────────────────┘ 'seven' ≡splay tt ⍝ new depth of key 'seven'. 3 val tt ← 'seven' ⍎splay tt ⍝ second access of key 'seven', display ⍕splay tt ⍝ moves it to the root. ┌→──────────────────────────┐ ↓ ┌five=5│ │ ┌four=4┘ │ │ ┌one=1┘ │ │seven=7┤ │ │ │ ┌six=6┐ │ │ │ │ └three=3│ │ └two=2┘ │ └───────────────────────────┘ 'seven' ≡splay tt ⍝ depth of key 'seven'. 1 ?splay tt ⍝ tree is: ok size=7, mean_depth=2, height=4. 1 7 2 4 tt ← tt ~splay 'seven' ⍝ tree with key 'seven' removed. display ⍕splay tt ┌→────────────────────────┐ ↓ ┌five=5│ │ ┌four=4┘ │ │ ┌one=1┘ │ │six=6┤ │ │ │ ┌three=3 │ │ └two=2┘ │ └─────────────────────────┘ ∊ splay tt ⍝ enlist of tree key=val pairs. ┌────────┬────────┬───────┬───────┬─────────┬───────┐ │┌────┬─┐│┌────┬─┐│┌───┬─┐│┌───┬─┐│┌─────┬─┐│┌───┬─┐│ ││five│5│││four│4│││one│1│││six│6│││three│3│││two│2││ │└────┴─┘│└────┴─┘│└───┴─┘│└───┴─┘│└─────┴─┘│└───┴─┘│ └────────┴────────┴───────┴───────┴─────────┴───────┘ ⍝ Notice how repeated retrieval of a particular key ⍝ lifts its node towards the root: ↑⍕splay\¨↑∘(⍎splay/)traj 10,⊂0 ∪splay foldl ⍳10 ⍝ see →traj← ┌──┬─────────────────────────────────────────┐ │10│1=1┐ │ │ │ └2=2┐ │ │ │ └3=3┐ │ │ │ └4=4┐ │ │ │ └5=5┐ │ │ │ └6=6┐ │ │ │ └7=7┐ │ │ │ └8=8┐ │ │ │ └9=9┐ │ │ │ └10=10│ ├──┼─────────────────────────────────────────┤ │10│1=1┐ │ │ │ └2=2┐ │ │ │ └3=3┐ │ │ │ └4=4┐ │ │ │ └5=5┐ │ │ │ └6=6┐ │ │ │ └7=7┐ │ │ │ │ ┌8=8│ │ │ │ ┌9=9┘ │ │ │ └10=10┘ │ ├──┼─────────────────────────────────────────┤ │10│1=1┐ │ │ │ └2=2┐ │ │ │ └3=3┐ │ │ │ └4=4┐ │ │ │ └5=5┐ │ │ │ │ ┌6=6 │ │ │ │ ┌7=7┤ │ │ │ │ │ │ ┌8=8 │ │ │ │ │ └9=9┘ │ │ │ └10=10┘ │ ├──┼─────────────────────────────────────────┤ │10│1=1┐ │ │ │ └2=2┐ │ │ │ └3=3┐ │ │ │ │ ┌4=4 │ │ │ │ ┌5=5┤ │ │ │ │ │ │ ┌6=6 │ │ │ │ │ └7=7┤ │ │ │ │ │ │ ┌8=8 │ │ │ │ │ └9=9┘ │ │ │ └10=10┘ │ ├──┼─────────────────────────────────────────┤ │10│1=1┐ │ │ │ │ ┌2=2 │ │ │ │ ┌3=3┤ │ │ │ │ │ │ ┌4=4 │ │ │ │ │ └5=5┤ │ │ │ │ │ │ ┌6=6 │ │ │ │ │ └7=7┤ │ │ │ │ │ │ ┌8=8 │ │ │ │ │ └9=9┘ │ │ │ └10=10┘ │ ├──┼─────────────────────────────────────────┤ │10│ ┌1=1┐ │ │ │ │ │ ┌2=2 │ │ │ │ └3=3┤ │ │ │ │ │ ┌4=4 │ │ │ │ └5=5┤ │ │ │ │ │ ┌6=6 │ │ │ │ └7=7┤ │ │ │ │ │ ┌8=8 │ │ │ │ └9=9┘ │ │ │10=10┘ │ └──┴─────────────────────────────────────────┘ See also: BST alists sbst avl redblack foldl traj Back to: contents Back to: Workspaces