/*********************** -*- Mode: C -*- *********************** * File : bintree_splay.c *--------------------------------------------------------------- * Description * =========== * An implementation of top-down splaying * D. Sleator * March 1992 * * "Splay trees", or "self-adjusting search trees" are a simple and * efficient data structure for storing an ordered set. The data * structure consists of a binary tree, without parent pointers, and * no additional fields. It allows searching, insertion, deletion, * deletemin, deletemax, splitting, joining, and many other * operations, all with amortized logarithmic performance. Since the * trees adapt to the sequence of requests, their performance on real * access patterns is typically even better. Splay trees are * described in a number of texts and papers [1,2,3,4,5]. * * The code here is adapted from simple top-down splay, at the bottom * of page 669 of [3]. It can be obtained via anonymous ftp from * spade.pc.cs.cmu.edu in directory /usr/sleator/public. * * The chief modification here is that the splay operation works even * if the item being splayed is not in the tree, and even if the tree * root of the tree is NULL. So the line: * * t = splay(i, t); * * causes it to search for item with key i in the tree rooted at t. * If it's there, it is splayed to the root. If it isn't there, * then the node put at the root is the last one before NULL that * would have been reached in a normal binary search for i. (It's a * neighbor of i in the tree.) This allows many other operations to * be easily implemented, as shown below. * * [1] "Fundamentals of data structures in C", Horowitz, Sahni, * and Anderson-Freed, Computer Science Press, pp 542-547. * [2] "Data Structures and Their Algorithms", Lewis and Denenberg, * Harper Collins, 1991, pp 243-251. * [3] "Self-adjusting Binary Search Trees" Sleator and Tarjan, * JACM Volume 32, No 3, July 1985, pp 652-686. * [4] "Data Structure and Algorithm Analysis", Mark Weiss, * Benjamin Cummins, 1992, pp 119-130. * [5] "Data Structures, Algorithms, and Performance", Derick Wood, * Addison-Wesley, 1993, pp 367-375. * * The following code was written by Daniel Sleator, and is released * in the public domain. * *--------------------------------------------------------------- * Author : Graeme McKerrell * Created On : Wed Jan 28 16:29:28 2004 * Status : TESTED *--------------------------------------------------------------- * HISTORY * 7-Dec-2004 Graeme McKerrell * Renamed to the "lub_" namespace * 5-May-2004 Graeme McKerrell * updates following review * 2-Mar-2004 Graeme McKerrell * Fixed to account for comparision logic being (node - key) * original algorithm expected (key - node) * 9-Feb-2004 Graeme McKerrell * updated to use new node,key comparison ordering * 28-Jan-2004 Graeme McKerrell * Adapted from original public domain code *--------------------------------------------------------------- * Copyright (C) 2004 3Com Corporation. All Rights Reserved. **************************************************************** */ #include "private.h" /*--------------------------------------------------------- */ lub_bintree_node_t *lub_bintree_splay(const lub_bintree_t * this, lub_bintree_node_t * t, const void *key) { /* Simple top down splay, not requiring "key" to be in the tree t. */ /* What it does is described above. */ lub_bintree_node_t N, *leftTreeMax, *rightTreeMin, *y; int comp; if (t == NULL) return t; N.left = N.right = NULL; leftTreeMax = rightTreeMin = &N; for (;;) { comp = lub_bintree_compare(this, t, key); if (comp > 0) { if (t->left == NULL) break; if (lub_bintree_compare(this, t->left, key) > 0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } rightTreeMin->left = t; /* link right */ rightTreeMin = t; t = t->left; } else if (comp < 0) { if (t->right == NULL) break; if (lub_bintree_compare(this, t->right, key) < 0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } leftTreeMax->right = t; /* link left */ leftTreeMax = t; t = t->right; } else { break; } } leftTreeMax->right = t->left; /* assemble */ rightTreeMin->left = t->right; t->left = N.right; t->right = N.left; /* return the new root */ return t; } /*--------------------------------------------------------- */