splaytree.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:19k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * splaytree.c:
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: splaytree.c 8205 2004-07-17 13:55:48Z asmax $
  6.  *
  7.  * Authors: Cyril Deguet <asmax@videolan.org>
  8.  *          code from projectM http://xmms-projectm.sourceforge.net
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. /*
  25.                 An implementation of top-down splaying
  26.                     D. Sleator <sleator@cs.cmu.edu>
  27.                           March 1992
  28.   "Splay trees", or "self-adjusting search trees" are a simple and
  29.   efficient data structure for storing an ordered set.  The data
  30.   structure consists of a binary tree, without parent pointers, and no
  31.   additional fields.  It allows searching, insertion, deletion,
  32.   deletemin, deletemax, splitting, joining, and many other operations,
  33.   all with amortized logarithmic performance.  Since the trees adapt to
  34.   the sequence of requests, their performance on real access patterns is
  35.   typically even better.  Splay trees are described in a number of texts
  36.   and papers [1,2,3,4,5].
  37.   The code here is adapted from simple top-down splay, at the bottom of
  38.   page 669 of [3].  It can be obtained via anonymous ftp from
  39.   spade.pc.cs.cmu.edu in directory /usr/sleator/public.
  40.   The chief modification here is that the splay operation works even if the
  41.   item being splayed is not in the tree, and even if the tree root of the
  42.   tree is NULL.  So the line:
  43.                               t = splay(i, t);
  44.   causes it to search for item with key i in the tree rooted at t.  If it's
  45.   there, it is splayed to the root.  If it isn't there, then the node put
  46.   at the root is the last one before NULL that would have been reached in a
  47.   normal binary search for i.  (It's a neighbor of i in the tree.)  This
  48.   allows many other operations to be easily implemented, as shown below.
  49.   [1] "Fundamentals of data structures in C", Horowitz, Sahni,
  50.        and Anderson-Freed, Computer Science Press, pp 542-547.
  51.   [2] "Data Structures and Their Algorithms", Lewis and Denenberg,
  52.        Harper Collins, 1991, pp 243-251.
  53.   [3] "Self-adjusting Binary Search Trees" Sleator and Tarjan,
  54.        JACM Volume 32, No 3, July 1985, pp 652-686.
  55.   [4] "Data Structure and Algorithm Analysis", Mark Weiss,
  56.        Benjamin Cummins, 1992, pp 119-130.
  57.   [5] "Data Structures, Algorithms, and Performance", Derick Wood,
  58.        Addison-Wesley, 1993, pp 367-375.
  59.   The following code was written by Daniel Sleator, and is released
  60.   in the public domain. It has been heavily modified by Carmelo Piccione,
  61.   (cep@andrew.cmu.edu), to suit personal needs, 
  62. */
  63. #include <stdio.h>
  64. #include <string.h>
  65. #include <stdlib.h>
  66. #include "common.h"
  67. #include "fatal.h"
  68. #include "splaytree_types.h"
  69. #include "splaytree.h"
  70. static inline splaynode_t * splay (void * key, splaynode_t * t, int * match_type, int (*compare)());
  71. static inline int free_splaynode(splaynode_t * splaynode, void (*free_key)());
  72. static inline void splay_traverse_helper (void (*func_ptr)(), splaynode_t * splaynode);
  73. static inline splaynode_t * splay_delete_helper(void * key, splaynode_t * t, int (*compare)(), void (*free_key)());
  74. static inline void splay_find_above_min_helper(void * max_key, void ** closest_key, splaynode_t * root, int (*compare)());
  75. static inline void splay_find_below_max_helper(void * max_key, void ** closest_key, splaynode_t * root, int (*compare)());
  76. static inline splaynode_t * new_splaynode(int type, void * key, void * data);
  77. static inline int splay_insert_node(splaynode_t * splaynode, splaytree_t * splaytree);
  78. static inline int splay_rec_size(splaynode_t * splaynode);
  79. /* Creates a splay tree given a compare key function, copy key function, and free key function.
  80.    Ah yes, the wonders of procedural programming */
  81. inline splaytree_t * create_splaytree(int (*compare)(), void * (*copy_key)(), void (*free_key)()) {
  82.   splaytree_t * splaytree;
  83.   /* Allocate memory for the splaytree struct */
  84.   if ((splaytree = (splaytree_t*)malloc(sizeof(splaytree_t))) == NULL)
  85.     return NULL;
  86.   /* Set struct entries */
  87.   splaytree->root = NULL;
  88.   splaytree->compare = compare;
  89.   splaytree->copy_key = copy_key;
  90.   splaytree->free_key = free_key;
  91.   
  92.   /* Return instantiated splay tree */
  93.   return splaytree;
  94. }
  95. /* Destroys a splay tree */
  96. inline int destroy_splaytree(splaytree_t * splaytree) {
  97.   /* Null argument check */
  98.   if (splaytree == NULL)
  99.     return FAILURE;
  100.   /* Recursively free all splaynodes in tree */
  101.   free_splaynode(splaytree->root, splaytree->free_key);
  102.   /* Free the splaytree struct itself */
  103.   free(splaytree);
  104.   
  105.   /* Done, return success */
  106.   return SUCCESS;
  107. }
  108. /* Recursively free all the splaynodes */
  109. static inline int free_splaynode(splaynode_t * splaynode, void (*free_key)()) {
  110.   /* Ok if this happens, a recursive base case */
  111.   if (splaynode == NULL)
  112.     return SUCCESS;
  113.   /* Free left node */
  114.   free_splaynode(splaynode->left, free_key);
  115.   
  116.   /* Free right node */
  117.   free_splaynode(splaynode->right, free_key);
  118.   
  119.   /* Free this node's key */
  120.   free_key(splaynode->key);
  121.   
  122.   /* Note that the data pointers are not freed here.
  123.      Should be freed with a splay traversal function */
  124.   
  125.   /* Free the splaynode structure itself */
  126.   free(splaynode);
  127.  
  128.   /* Finished, return success */
  129.   return SUCCESS;
  130. }
  131. /* Traverses the entire splay tree with the given function func_ptr */
  132. inline void splay_traverse(void (*func_ptr)(), splaytree_t * splaytree) {
  133.   /* Null argument check */
  134.   if (splaytree == NULL)
  135.     return; 
  136.   if (func_ptr == NULL)
  137. return;
  138.   
  139.   /* Call recursive helper function */
  140.   splay_traverse_helper(func_ptr, splaytree->root);
  141.   return;
  142. }
  143. /* Helper function to traverse the entire splaytree */
  144. static inline void splay_traverse_helper (void (*func_ptr)(), splaynode_t * splaynode) {  
  145.   /* Normal if this happens, its a base case of recursion */
  146.   if (splaynode == NULL)
  147.     return;
  148.   /* Recursively traverse to the left */
  149.   splay_traverse_helper(func_ptr, splaynode->left);
  150.   
  151.   
  152.   /* Node is a of regular type, so its ok to perform the function on it */
  153.   if (splaynode->type == REGULAR_NODE_TYPE)
  154.    func_ptr(splaynode->data);
  155.   
  156.   /* Node is of symbolic link type, do nothing */
  157.   else if (splaynode->type == SYMBOLIC_NODE_TYPE)
  158. ;
  159.   
  160.   /* Unknown node type */
  161.   else
  162.     ;
  163.   
  164.   /* Recursively traverse to the right */
  165.   splay_traverse_helper(func_ptr, splaynode->right);
  166.   /* Done */
  167.   return;
  168. }
  169. /* Find the node corresponding to the given key in splaytree, return its data pointer */
  170. inline void * splay_find(void * key, splaytree_t * splaytree) {
  171.   splaynode_t * splaynode;
  172.   int match_type;
  173.   if (key == NULL)
  174.   return NULL;
  175.   
  176.   if (splaytree == NULL)
  177.   return NULL;
  178.   
  179.   splaynode = splaytree->root;
  180.   
  181.   /* Bring the targeted splay node to the top of the splaytree */
  182.   splaynode = splay(key, splaynode, &match_type, splaytree->compare);
  183.   splaytree->root = splaynode;
  184.   
  185.   
  186.   /* We only want perfect matches, so return null when match isn't perfect */
  187.   if (match_type == CLOSEST_MATCH) 
  188.     return NULL;
  189.   /* This shouldn't happen because of the match type check, but whatever */
  190.   if (splaytree->root == NULL)
  191.   return NULL;
  192.   
  193.   /* Node is a regular type, return its data pointer */
  194.   if (splaytree->root->type == REGULAR_NODE_TYPE) /* regular node */
  195.    return splaytree->root->data;
  196.   
  197.   /* If the node is a symlink, pursue one link */
  198.   if (splaytree->root->type == SYMBOLIC_NODE_TYPE) /* symbolic node */
  199. return ((splaynode_t*)splaytree->root->data)->data;
  200.     
  201.   
  202.   /* Unknown type */
  203.   return NULL;
  204. }
  205. /* Gets the splaynode that the given key points to */
  206. inline splaynode_t * get_splaynode_of(void * key, splaytree_t * splaytree) {
  207.   splaynode_t * splaynode;
  208.   int match_type;
  209.   
  210.   /* Null argument checks */
  211.   if (splaytree == NULL)
  212.   return NULL;
  213.   
  214.   if (key == NULL)
  215.   return NULL;
  216.   
  217.   splaynode = splaytree->root;
  218.   /* Find the splaynode */
  219.   splaynode = splay(key, splaynode, &match_type, splaytree->compare);
  220.   splaytree->root = splaynode;
  221.  
  222.   /* Only perfect matches are valid */
  223.   if (match_type == CLOSEST_MATCH)
  224.     return NULL;
  225.   /* Return the perfect match splay node */
  226.   return splaynode;
  227. }
  228. /* Finds the desired node, and changes the tree such that it is the root */
  229. static inline splaynode_t * splay (void * key, splaynode_t * t, int * match_type, int (*compare)()) {
  230.   
  231. /* Simple top down splay, not requiring key to be in the tree t. 
  232.    What it does is described above. */
  233.  
  234.     splaynode_t N, *l, *r, *y;
  235.     *match_type = CLOSEST_MATCH;
  236.   
  237. if (t == NULL) return t;
  238.     N.left = N.right = NULL;
  239.     l = r = &N;
  240.   
  241.     for (;;) {
  242. if (compare(key, t->key) < 0) {
  243.     if (t->left == NULL) break;
  244.     if (compare(key, t->left->key) < 0) {
  245. y = t->left;                           /* rotate right */
  246. t->left = y->right;
  247. y->right = t;
  248. t = y;
  249. if (t->left == NULL) break;
  250.     }
  251.     r->left = t;                               /* link right */
  252.     r = t;
  253.     t = t->left;
  254. } else if (compare(key, t->key) > 0) {
  255.     if (t->right == NULL) break;
  256.     if (compare(key, t->right->key) > 0) {
  257. y = t->right;                          /* rotate left */
  258. t->right = y->left;
  259. y->left = t;
  260. t = y;
  261. if (t->right == NULL) break;
  262.     }
  263.     l->right = t;                              /* link left */
  264.     l = t;
  265.     t = t->right;
  266. } else {
  267.   *match_type = PERFECT_MATCH;
  268.   break;
  269. }
  270.     }
  271.     l->right = t->left;                                /* assemble */
  272.     r->left = t->right;
  273.     t->left = N.right;
  274.     t->right = N.left;
  275.     
  276.     return t;
  277.     //return NULL;
  278. }
  279. /* Deletes a splay node from a splay tree. If the node doesn't exist
  280.    then nothing happens */
  281. inline int splay_delete(void * key, splaytree_t * splaytree) {
  282.   
  283.   splaynode_t * splaynode;
  284.   /* Use helper function to delete the node and return the resulting tree */
  285.   if ((splaynode = splay_delete_helper(key, splaytree->root, splaytree->compare, splaytree->free_key)) == NULL)
  286.   return FAILURE;
  287.   
  288.   /* Set new splaytree root equal to the returned splaynode after deletion */
  289.   splaytree->root = splaynode;
  290.   
  291.   /* Finished, no errors */
  292.   return SUCCESS;
  293. }
  294. /* Deletes a splay node */
  295. static inline splaynode_t * splay_delete_helper(void * key, splaynode_t * splaynode, int (*compare)(), void (*free_key)()) {
  296.     splaynode_t * new_root;
  297.     int match_type;
  298. /* Argument check */
  299.     if (splaynode == NULL) 
  300. return NULL;
  301.     splaynode = splay(key, splaynode, &match_type, compare);
  302. /* If entry wasn't found, quit here */
  303. if (match_type == CLOSEST_MATCH) 
  304. return NULL;
  305. /* If the targeted node's left pointer is null, then set the new root
  306.    equal to the splaynode's right child */
  307. if (splaynode->left == NULL) {
  308.     new_root = splaynode->right;
  309. /* Otherwise, do something I don't currently understand */
  310. else {
  311.     new_root = splay(key, splaynode->left, &match_type, compare);
  312.     new_root->right = splaynode->right;
  313. }
  314. /* Set splay nodes children pointers to null */
  315. splaynode->left = splaynode->right = NULL;
  316. /* Free the splaynode (and only this node since its children are now empty */
  317. free_splaynode(splaynode, free_key);
  318. /* Return the resulting tree */
  319. return new_root;
  320. }
  321. /* Create a new splay node type */
  322. static inline splaynode_t * new_splaynode(int type, void * key, void * data) {
  323. splaynode_t * splaynode;
  324. /* Argument checks */
  325. if (data == NULL)
  326. return NULL;
  327. if (key == NULL)
  328. return NULL;
  329. /* Creates the new splay node struct */
  330. if ((splaynode = (splaynode_t*)malloc(sizeof(splaynode_t))) == NULL)
  331. return NULL;
  332. splaynode->data = data;
  333. splaynode->type = type;
  334. splaynode->key = key;
  335. /* Return the new splay node */
  336. return splaynode;
  337. }
  338. /* Inserts a link into the splay tree */
  339. inline int splay_insert_link(void * alias_key, void * orig_key, splaytree_t * splaytree) {
  340.    splaynode_t * splaynode, * data_node;
  341.    void * key_clone;
  342.    /* Null arguments */
  343.    if (splaytree == NULL)
  344. return FAILURE;
  345.    
  346.    if (alias_key == NULL)
  347.     return FAILURE;
  348.    if (orig_key == NULL)
  349.     return FAILURE;
  350.    
  351.    /* Find the splaynode corresponding to the original key */
  352.    if ((data_node = get_splaynode_of(orig_key, splaytree)) == NULL)
  353.    return FAILURE;
  354.    
  355.    /* Create a new splay node of symbolic link type */
  356.    if ((splaynode = new_splaynode(SYMBOLIC_NODE_TYPE, (key_clone = splaytree->copy_key(alias_key)), data_node)) == NULL) {
  357. splaytree->free_key(key_clone);
  358. return OUTOFMEM_ERROR;
  359.    }
  360.    /* Insert the splaynode into the given splaytree */
  361.    if ((splay_insert_node(splaynode, splaytree)) < 0) {
  362.      splaynode->left=splaynode->right = NULL;
  363.      free_splaynode(splaynode, splaytree->free_key);
  364.      return FAILURE;
  365.    }
  366.    /* Done, return success */
  367.    return SUCCESS;
  368. }
  369. /* Inserts 'data' into the 'splaytree' paired with the passed 'key' */
  370. inline int splay_insert(void * data, void * key, splaytree_t * splaytree) {
  371. splaynode_t * splaynode;
  372. void * key_clone;
  373. /* Null argument checks */
  374. if (splaytree == NULL) {
  375.     return FAILURE;
  376. }
  377. if (key == NULL)
  378. return FAILURE;
  379. /* Clone the key argument */
  380. key_clone = splaytree->copy_key(key);
  381. /* Create a new splaynode (of regular type) */
  382. if ((splaynode = new_splaynode(REGULAR_NODE_TYPE, key_clone, data)) == NULL) {
  383. splaytree->free_key(key_clone);
  384. return OUTOFMEM_ERROR;
  385. }
  386.        
  387. /* Inserts the splaynode into the splaytree */
  388. if (splay_insert_node(splaynode, splaytree) < 0) {
  389.   splaynode->left=splaynode->right=NULL;
  390.   free_splaynode(splaynode, splaytree->free_key);
  391.   return FAILURE;
  392. }
  393.      
  394. return SUCCESS;
  395. }
  396. /* Helper function to insert splaynodes into the splaytree */
  397. static inline int splay_insert_node(splaynode_t * splaynode, splaytree_t * splaytree) {
  398.   int match_type;
  399.   int cmpval;
  400.   void * key;
  401.   splaynode_t * t;
  402.   /* Null argument checks */
  403.   if (splaytree == NULL)
  404.     return FAILURE;
  405.   if (splaynode == NULL)
  406. return FAILURE;
  407.   
  408.   key = splaynode->key;
  409.   
  410.   t = splaytree->root; 
  411.   /* Root is null, insert splaynode here */
  412.   if (t == NULL) {
  413. splaynode->left = splaynode->right = NULL;
  414. splaytree->root = splaynode;
  415. return SUCCESS;
  416.   }
  417.   
  418.   t = splay(key, t, &match_type, splaytree->compare);
  419.   
  420.   if ((cmpval = splaytree->compare(key,t->key)) < 0) {
  421. splaynode->left = t->left;
  422. splaynode->right = t;
  423. t->left = NULL;
  424. splaytree->root = splaynode;
  425. return SUCCESS;
  426.   } 
  427.   else if (cmpval > 0) {
  428. splaynode->right = t->right;
  429. splaynode->left = t;
  430. t->right = NULL; 
  431. splaytree->root = splaynode;
  432. return SUCCESS;
  433.    } 
  434.    
  435.    /* Item already exists in tree, don't reinsert */
  436.   else {
  437.     
  438.     return FAILURE;
  439.   }
  440. }
  441. /* Returns the 'maximum' key that is less than the given key in the splaytree */
  442. inline void * splay_find_below_max(void * key, splaytree_t * splaytree) {
  443. void * closest_key;
  444. if (splaytree == NULL)
  445. return NULL;
  446. if (splaytree->root == NULL)
  447. return NULL;
  448. if (key == NULL)
  449. return NULL;
  450. closest_key = NULL;
  451. splay_find_below_max_helper(key, &closest_key, splaytree->root, splaytree->compare);
  452. if (closest_key == NULL) return NULL;
  453. return splay_find(closest_key, splaytree);
  454. }
  455. /* Returns the 'minimum' key that is greater than the given key in the splaytree */
  456. inline void * splay_find_above_min(void * key, splaytree_t * splaytree) {
  457. void * closest_key;
  458. if (splaytree == NULL)
  459. return NULL;
  460. if (splaytree->root == NULL)
  461. return NULL;
  462. if (key == NULL)
  463. return NULL;
  464. closest_key = NULL;
  465. splay_find_above_min_helper(key, &closest_key, splaytree->root, splaytree->compare);
  466. if (closest_key == NULL) { 
  467. return NULL;
  468. }
  469. return splay_find(closest_key, splaytree);
  470. }
  471. /* Helper function */
  472. static inline void splay_find_below_max_helper(void * min_key, void ** closest_key, splaynode_t * root, int (*compare)()) {
  473. /* Empty root, return*/
  474. if (root == NULL)
  475. return;
  476. /* The root key is less than the previously found closest key.
  477.    Also try to make the key non null if the value is less than the max key */
  478. if ((*closest_key == NULL) || (compare(root->key, *closest_key) < 0)) {
  479. /*  The root key is less than the given max key, so this is the
  480. smallest change from the given max key */
  481. if (compare(root->key, min_key) > 0) {
  482. *closest_key = root->key;
  483. /* Look right again in case even a greater key exists that is 
  484.    still less than the given max key */
  485. splay_find_below_max_helper(min_key, closest_key, root->left, compare);
  486. }
  487. /* The root key is greater than the given max key, and greater than 
  488.    the closest key, so search left */
  489. else {
  490. splay_find_below_max_helper(min_key, closest_key, root->right, compare);
  491. }
  492. }
  493. /* The root key is less than the found closest key, search right */
  494. else {
  495. splay_find_below_max_helper(min_key, closest_key, root->left, compare);
  496. }
  497. }
  498. /* Helper function */
  499. static inline void splay_find_above_min_helper(void * max_key, void ** closest_key, splaynode_t * root, int (*compare)()) {
  500. /* Empty root, stop */
  501. if (root == NULL)
  502. return;
  503. /* The root key is greater than the previously found closest key.
  504.    Also try to make the key non null if the value is less than the min key */
  505. if ((*closest_key == NULL) || (compare(root->key, *closest_key) > 0)) {
  506. /*  The root key is greater than the given min key, so this is the
  507. smallest change from the given min key */
  508. if (compare(root->key, max_key) < 0) {
  509. *closest_key = root->key;
  510.    /* Look left again in case even a smaller key exists that is 
  511.   still greater than the given min key */
  512. splay_find_above_min_helper(max_key, closest_key, root->right, compare);
  513. }
  514. /* The root key is less than the given min key, and less than 
  515.    the closest key, so search right */
  516. else {
  517. splay_find_above_min_helper(max_key, closest_key, root->left, compare);
  518. }
  519. }
  520. /* The root key is greater than the found closest key, search left */
  521. else {
  522. splay_find_above_min_helper(max_key, closest_key, root->right, compare);
  523. }
  524. }
  525. /* Find the minimum entry of the splay tree */
  526. inline void * splay_find_min(splaytree_t * t) {
  527. splaynode_t * splaynode;
  528. if (t == NULL)
  529. return NULL;
  530. if (t->root == NULL)
  531. return NULL;
  532. splaynode = t->root;
  533. while (splaynode->left != NULL)
  534. splaynode= splaynode->left;
  535. return splaynode->data;
  536. }
  537. /* Find the maximum entry of the splay tree */
  538. inline void * splay_find_max(splaytree_t * t) {
  539. splaynode_t * splaynode;
  540. if (t == NULL)
  541. return NULL;
  542. if (t->root == NULL)
  543. return NULL;
  544. splaynode = t->root;
  545.  
  546. while (splaynode->right != NULL) {
  547.   printf("data:%dn", *(int*)splaynode->key);
  548. splaynode = splaynode->right;
  549. }
  550. return splaynode->data;
  551. }
  552. inline int splay_size(splaytree_t * t) {
  553. if (t == NULL)
  554.   return 0;
  555. if (t->root == NULL)
  556.   return 0;
  557. return splay_rec_size(t->root);
  558.  
  559. }
  560. static inline int splay_rec_size(splaynode_t * splaynode) {
  561.   if (!splaynode)
  562.     return 0;
  563.   return 1 + splay_rec_size(splaynode->left) + splay_rec_size(splaynode->right);
  564. }