注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
 帮助
  51CTO博客 > 技术圈 > 程序设计 > 讨论区
 
 
守住每一天 本周内更新[楼主]
 
 
圈主
圈积分:242
发短消息 博客
[算法] Size Balance Tree和Treap的ADT接口和实现  回复:0 阅读:89 2008-02-15 18:51:37
 
1M个整数插入删除,不优化的情况下, SBT费时5.2秒,Treap才2.1秒,说SBT比Treap快,怎么不觉得了,不明白
文件:include/Item.h

/*-----------------------------------------------------------
        Item.h
        作者: QingXiaoming, 12-03, 2007([url]http://www.cublog.com/augustusqing/[/url])
        您可以自由的传播,修改这份代码,转载处请注明原作者
-------------------------------------------------------------*/

#ifndef ITEM_H
#define ITEM_H

typedef int Item;

#endif

文件:include/SBTree_ADT.h

/*-----------------------------------------------------------
        SBT的ADT接口
        Author: QingXiaoming, 12-05, 2007([url]http://www.cublog.com/augustusqing/[/url]
        您可以自由拷贝,修改,传播这份代码,但请注明原作者
-------------------------------------------------------------*/

#ifndef SBTREE_ADT_H
#define SBTREE_ADT_H
#include "Item.h"
typedef struct SBTree *SBTree;
typedef struct SBTreeNode *SBTreeLink;

SBTree initSBTree(void);
int emptySBTree(SBTree);
int sizeSBTree(SBTree);
void showSBTreeNode(SBTreeLink);
void destroySBTree(SBTree);
void pretravseSBTree(SBTree);
void midtravseSBTree(SBTree);
int rankSBTree(SBTree, SBTreeLink);

Item seqSBTree(SBTree, int);
SBTreeLink findSBTree(SBTree, Item);
Item preSBTree(SBTree, Item);
Item sucSBTree(SBTree, Item);
Item minSBTree(SBTree);
Item maxSBTree(SBTree);
void insertSBTree(SBTree, Item);
SBTreeLink deleteSBTree(SBTree, Item);

#endif

文件:include/Treap_ADT.h

/*-----------------------------------------------------------
        Treap的ADT接口
        作者: QingXiaoming, 12-04, 2007([url]http://www.cublog.com/augustusqing/[/url])
        您可以自由的传播,修改这份代码,转载处请注明原作者
-------------------------------------------------------------*/

#ifndef TREAP_ADT_H
#define TREAP_ADT_H
#include "Item.h"
typedef struct treap *Treap;
typedef struct treapnode *TreapLink;

Treap initTreap(int);
int emptyTreap(Treap);
TreapLink findTreapNode(Treap, Item);
void insertTreap(Treap, Item);
TreapLink deleteTreap(Treap, Item);
void midtravseTreap(Treap);
void pretravseTreap(Treap);
void destroyTreap(Treap);
#endif

文件:include/SBTree_ADT_user.c

/*-----------------------------------------------------------
        SBTree的ADT客户程序
        Author: QingXiaoming, 12-05, 2007([url]http://www.cublog.com/augustusqing/[/url]
        您可以自由拷贝,修改,传播这份代码,但请注明原作者
-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "include/SBTree_ADT.h"

int main(int argc, char *argv[])
{
    int i, N = atoi(argv[1]);//, M = atoi(argv[2]);
    Item t;//,ta;
    SBTree tree = initSBTree();
    //SBTreeLink x;
    long start, stop;
    srand((unsigned)clock());
    start = clock();
    for (i = 0; i < N; i++)
    {
        t = rand() + i;
        insertSBTree(tree, t);
    }
    //pretravseSBTree(tree);
    printf("\n");
    //midtravseSBTree(tree);
    //printf("\n");
    /*
    t = seqSBTree(tree, M);
    ta = sucSBTree(tree, t);
    printf("Size:%d, Rank %d is : %d, Min:%d, Max:%d, Pre:%d, Suc:%d\n",
           sizeSBTree(tree), M, t, minSBTree(tree), maxSBTree(tree), preSBTree(tree, t), sucSBTree(tree, t));
    x = deleteSBTree(tree, t);
    free(x);
    x = findSBTree(tree, ta);
    showSBTreeNode(x);
    printf("After delete %d,Size:%d,  Min:%d, Max:%d, Rank of suc:%d\n",
           t, sizeSBTree(tree), minSBTree(tree), maxSBTree(tree), rankSBTree(tree, x));
   
    printf("Befor destroy, Tree is %s\n", emptySBTree(tree) ? "Empty" : "Not Empty");
    */
    destroySBTree(tree);
   
    printf("After destroy, Tree is %s\n", emptySBTree(tree) ? "Empty" : "Not Empty");
    stop = clock();
    printf("Time :%ld", stop - start);
    return 0;
}

文件:include/Treap_ADT_user.c

/*-----------------------------------------------------------
        Treap的ADT客户程序
        作者: QingXiaoming, 12-04, 2007([url]http://www.cublog.com/augustusqing/[/url])
        您可以自由的传播,修改这份代码,转载处请注明原作者
-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "include/Treap_ADT.h"

int main(int argc, char *argv[])
{
    int i, N = atoi(argv[1]);
    Item t;
    Treap tree = initTreap(N);
    //TreapLink x;
    long start, stop;
    start = clock();
    for (i = 0; i < N; i++)
    {
        t = i;
        insertTreap(tree, t);
    }
    //pretravseTreap(tree);
    printf("\n");
    //midtravseTreap(tree);
    /*
    for (i = 2;i < N; i += 2)
    {
        x = deleteTreap(tree, i);
        free(x);
        printf("\n");
        pretravseTreap(tree);
        printf("\n");
        midtravseTreap(tree);  
        system("pause");   
    }
    */
    destroyTreap(tree);
    stop = clock();
    printf("Time :%ld", stop - start);
    return 0;
}
 
文件:SBTree_ADT.c

/*-----------------------------------------------------------
        SBTree的ADT实现
        作Author: QingXiaoming, 12-05, 2007([url]http://www.cublog.com/augustusqing/[/url]
        您可以自由拷贝,修改,传播这份代码,但请注明原作者
-------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include "include/SBTree_ADT.h"

struct SBTreeNode {
       Item item;
       SBTreeLink lchild;
       SBTreeLink rchild;
       int size;
       };
struct SBTree {
       SBTreeLink root;
       };
      
static SBTreeLink NEW(Item item)
{
       SBTreeLink x = NULL;
       x = malloc(sizeof(*x));
       if (!x){perror("Get memory for Node error");return NULL;}
       x->item = item;
       x->lchild = x->rchild = NULL;
       x->size = 1;
       return x;
}

SBTree initSBTree()
{
       SBTree x = NULL;
       x = malloc(sizeof(*x));
       if (!x){perror("Get memory for tree error");return NULL;}
       x->root = NULL;
       return x;
}

int emptySBTree(SBTree tree)
{
    return tree->root == NULL;
}
void showSBTreeNode(SBTreeLink x)
{
     printf("Item=%d, Size=%d, Left=%d, Right=%d\n",x->item, x->size, (NULL != x->lchild)?x->lchild->item:-1,(NULL != x->rchild)?x->rchild->item:-1);
}

int sizeSBTree(SBTree tree)
{
    if(!tree || !tree->root){perror("Size a NULL tree");return -1;}
    return tree->root->size;
}

Item maxSBTree(SBTree tree)
{
     if(!tree || !tree->root){perror("Max a NULL tree");return -1;}
     return seqSBTree(tree, sizeSBTree(tree));
}

Item minSBTree(SBTree tree)
{
     if(!tree || !tree->root){perror("Min a NULL tree");return -1;}
     return seqSBTree(tree, 1);
}

SBTreeLink findSBTree(SBTree tree, Item item)
{
    SBTreeLink x  = tree->root;
    while (x && item != x->item)
    {
          x = (item < x->item) ? x->lchild : x->rchild;
    }
    return x;
}

Item preSBTree(SBTree tree, Item item)
{
     int r;
     SBTreeLink x = findSBTree(tree, item);
     if (!x){printf("No item %d in the tree", item);return -1;}
     r = rankSBTree(tree, x);
     if (1 == r){printf("item %d is No.1, Can't Pre this item", item);return -1;}
     return seqSBTree(tree, r - 1);  
}

Item sucSBTree(SBTree tree, Item item)
{
     int r;
     SBTreeLink x = findSBTree(tree, item);
     if (!x){printf("No item %d in the tree", item);return -1;}
     r = rankSBTree(tree, x);
     if (sizeSBTree(tree) == r){printf("item %d is No.MAX, Can't Suc this item", item);return -1;}
     return seqSBTree(tree, r + 1);
}

static void pretravseSBTreeNode(SBTreeLink link)
{
       if (link)
       {
           showSBTreeNode(link);
           pretravseSBTreeNode(link->lchild);
           pretravseSBTreeNode(link->rchild);
       }
}

void pretravseSBTree(SBTree tree)
{
     return pretravseSBTreeNode(tree->root);
}

static void midtravseSBTreeNode(SBTreeLink link)
{
       if (link)
       {
           midtravseSBTreeNode(link->lchild);
           showSBTreeNode(link);
           midtravseSBTreeNode(link->rchild);
       }
}
void midtravseSBTree(SBTree tree)
{
     return midtravseSBTreeNode(tree->root);
}

static void Left_Rotate(SBTreeLink *link)
{
       SBTreeLink y, x = *link;
       if (!x || !x->rchild){perror("Cant Right Rotate NULL node or NULL lchild");return;}
       y = x->rchild;
       x->rchild = y->lchild;
       *link = y;
       y->lchild = x;
       y->size = x->size;
       x->size = ((x->lchild != NULL) ? x->lchild->size: 0) + ((x->rchild != NULL) ? x->rchild->size: 0) + 1;
}

static void Right_Rotate(SBTreeLink *link)
{
       SBTreeLink y, x = *link;
       if (!x || !x->lchild){perror("Cant Right Rotate NULL node or NULL lchild");return;}
       y = x->lchild;
       x->lchild = y->rchild;
       *link = y;
       y->rchild = x;
       y->size = x->size;
       x->size = ((x->lchild != NULL) ? x->lchild->size: 0) + ((x->rchild != NULL) ? x->rchild->size: 0) + 1;
}

static void maintainSBTree(SBTreeLink *link, int flag)
{
       SBTreeLink t = *link;
       if(!t)return;
       if (!flag)
       {
           if (t->lchild && t->lchild->lchild && (!t->rchild || t->lchild->lchild->size > t->rchild->size))
           {
                Right_Rotate(link);
           }
           else if (t->lchild && t->lchild->rchild && (!t->rchild || t->lchild->rchild->size > t->rchild->size))
           {
                Left_Rotate(&(t->lchild));
                Right_Rotate(link);
           }
           else return;
       }
       else
       {
           if (t->rchild && t->rchild->rchild && (!t->lchild || t->rchild->rchild->size > t->lchild->size))
           {
                Left_Rotate(link);
           }
           else if (t->rchild && t->rchild->lchild && (!t->lchild || t->rchild->lchild->size > t->lchild->size))
           {
                Right_Rotate(&(t->rchild));
                Left_Rotate(link);
           }
           else return;
       }
       maintainSBTree(&(t->lchild), 0);
       maintainSBTree(&(t->rchild), 1);
       maintainSBTree(link, 0);
       maintainSBTree(link, 1);
}
static void insertSBTreeNode(SBTreeLink *link, Item item)
{
      SBTreeLink x = *link;
      if (!x)
      {
          *link = NEW(item);
          return;
      }
      else
      {
          x->size += 1;
          insertSBTreeNode((item < x->item) ? &(x->lchild) : &(x->rchild), item);
          maintainSBTree(link, item > x->item);
      }
}

void insertSBTree(SBTree tree, Item item)
{
      SBTreeLink x = findSBTree(tree, item);
      if (x)
      {
          //printf("Cant insert a Exist item into tree!\n");
          return;
      }
      return insertSBTreeNode(&tree->root, item);
}

SBTreeLink deleteSBTree(SBTree tree, Item item)
{
    Item t;
    SBTreeLink n, m, z, y, x = tree->root;
    if (!x){perror("Cant delete node from NULL tree");return NULL;}
    if (item == x->item && !x->rchild)
    {
        tree->root = x->lchild;
        return x;
    }// find the node with item
    while (x && (item != x->item))
    {
          z = x;
          x = (item < x->item) ? x->lchild : x->rchild;        
    }//find the x's father node
    if (x)
    {
          if (x->rchild)
          {
              z = x;
              y = x->rchild;
              while (y->lchild)
              {
                    z = y;
                    y = y->lchild;
              }
          }// find y, the node will really be deleted, and his father
          else
          {
              y = x;
          }
    }
    else
    {
        printf("No item %d in the SBTree\n", item);
        return NULL;
    }
    //handle the y's child
    m = y->lchild ? y->lchild : y->rchild;
    if (y == z->lchild)
    {
          z->lchild = m;
    }
    else
    {
          z->rchild = m;
    }
    n = tree->root;
    while (n != z)
    {
          n->size--;
          n = item < n->item ? n->lchild : n->rchild;
    }//modify the size, from root the the y's parent
    z->size--;// also y's father
    if(x != y)
    {
         t = x->item; x->item = y->item; y->item = t;
    }
    return y;
}

static Item seqSBTreeNode(SBTreeLink link, int i)
{
    int r;
    if (!link){perror("You want to Seq a non-exist number Node");return -1;}
    r = (NULL != link->lchild) ? (link->lchild->size + 1) : 1;
    if (i == r){return  link->item;}
    else return (i < r) ? seqSBTreeNode(link->lchild, i) : seqSBTreeNode(link->rchild, i-r);
}
Item seqSBTree(SBTree tree, int i)
{
    return seqSBTreeNode(tree->root, i);
}

int rankSBTree(SBTree tree , SBTreeLink link)
{
    int r = 0;
    SBTreeLink x = tree->root;
    if(!tree->root || !link){perror("You want to Rank a non-exist Node or NULL tree");return -1;}
    while (x != link)
    {
          if (link->item > x->item)
          {
              r += (NULL != x->lchild) ? (x->lchild->size + 1) : 1;
              x = x->rchild;
          }
          else
          {
              x = x->lchild;
          }   
    }
    r += (NULL != x->lchild) ? (x->lchild->size + 1) : 1;
    return r;
}

void destroySBTree(SBTree tree)
{
     SBTreeLink y, x = tree->root;
     while (x)
     {
           y = deleteSBTree(tree, x->item);
           free(y);
           x = tree->root;
     }
}

文件:Treap_ADT.c

/*-----------------------------------------------------------
        Treap的ADT实现
        作者: QingXiaoming, 12-04, 2007([url]http://www.cublog.com/augustusqing/[/url])
        您可以自由的传播,修改这份代码,转载处请注明原作者
-------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include "include/Treap_ADT.h"

struct treapnode {
       Item item;
       TreapLink parent;
       TreapLink lchild;
       TreapLink rchild;
       int prio;
       };
struct treap {
       TreapLink root;
       };

static int priobase = 1;
static TreapLink NEW(Item item, TreapLink parent);
static void Left_Rotate(Treap tree, TreapLink x);
static void Right_Rotate(Treap tree, TreapLink x);
static void pretravseTreapNode(TreapLink root);
static void midtravseTreapNode(TreapLink root);

static TreapLink NEW(Item item, TreapLink parent)
{
       TreapLink x = NULL;
       x = malloc(sizeof(*x));
       if (!x){perror("Get memory for Node error");return NULL;}
       x->item = item;
       x->parent = parent;
       x->lchild = NULL;
       x->rchild = NULL;
       x->prio = rand()%priobase;
       return x;
}

Treap initTreap(int N)
{
      Treap x = NULL;
      x = malloc(sizeof(*x));
      if (!x){perror("Get memory for Treap error");return NULL;}
      x->root = NULL;
      priobase = N;
      return x;
}

int emptyTreap(Treap tree)
{
    return tree->root == NULL;
}

TreapLink findTreapNode(Treap tree, Item item)
{
    TreapLink x = tree->root;
    while (NULL != x && item != x->item)
    {
          x = (item < x->item) ? x->lchild : x->rchild;
    }
    return x;
}

static void Left_Rotate(Treap tree, TreapLink x)
{
       TreapLink y;
       if (!x || !x->rchild){perror("Cant Left_Rotate NULL  or NULL rchild");exit(-1);}
       y = x->rchild;
       x->rchild = y->lchild;
       if (y->lchild)
       {
           y->lchild->parent = x;
       }
       y->parent = x->parent;
       if (x == tree->root)
       {
           tree->root = y;
       }
       else
       {
           if ( x == x->parent->lchild)
           {
                x->parent->lchild = y;
           }
           else
           {
               x->parent->rchild = y;
           }
       }
       y->lchild = x;
       x->parent = y;
}

static void Right_Rotate(Treap tree, TreapLink x)
{
       TreapLink y;
       if (!x || !x->rchild){perror("Cant Right_Rotate NULL  or NULL rchild");exit(-1);}
       y = x->lchild;
       x->lchild = y->rchild;
       if (y->rchild)
       {
           y->rchild->parent = x;
       }
       y->parent = x->parent;
       if (x == tree->root)
       {
           tree->root = y;
       }
       else
       {
           if ( x == x->parent->lchild)
           {
                x->parent->lchild = y;
           }
           else
           {
               x->parent->rchild = y;
           }
       }
       y->rchild = x;
       x->parent = y;
}

static void fixinsertTreap(Treap tree, TreapLink link)
{

    while (NULL != link->parent && link->prio < link->parent->prio)
    {
          if (link == link->parent->lchild)
          {
              Right_Rotate(tree, link->parent);
          }
          else
          {
              Left_Rotate(tree, link->parent);
          }
    }
}

void insertTreap(Treap tree, Item item)
{
     TreapLink y, x = tree->root;
     if (!tree->root)
     {
         x = tree->root = NEW(item, tree->root);
         return;
     }
     while (NULL != x)
     {
           y = x;
           x = (item < x->item) ? x->lchild : x->rchild;
     }
     if (item < y->item)
     {
         x = y->lchild = NEW(item, y);
     }
     else
     {
         x = y->rchild = NEW(item, y);
     }
     fixinsertTreap(tree, x);
}

TreapLink deleteTreap(Treap tree, Item item)
{
    TreapLink z, y, x = findTreapNode(tree, item);
    Item t;
    if (!x){printf("Cant find item:%d to delete!\n", item);return NULL;}
    if (NULL != x->rchild)
    {
        y = x->rchild;
        while (NULL != y->lchild)
        {
              y = y->lchild;
        }
    }
    else
    {
        y = x;
    }
    z = (NULL != y->lchild) ? y->lchild : y->rchild;
    if (NULL != z)
    {
        z->parent = y->parent;
    }
    if (NULL != y->parent)
    {
        if (y == y->parent->lchild)
        {
            y->parent->lchild = z;
        }
        else
        {
            y->parent->rchild = z;
        }
    }
    else
    {
        tree->root = z;
    }
    if (y != x)
    {
          t = x->item;
          x->item = y->item;
          y->item = t;
    }
    return y;
}

static void midtravseTreapNode(TreapLink root)
{
     if (NULL != root)
     {
         midtravseTreapNode(root->lchild);
         printf("Item:%5d, Prio:%5d\n", root->item, root->prio);
         midtravseTreapNode(root->rchild);        
     }
}

static void pretravseTreapNode(TreapLink root)
{
     if (NULL != root)
     {
         printf("Item:%5d, Prio:%5d\n", root->item, root->prio);
         pretravseTreapNode(root->lchild);
         pretravseTreapNode(root->rchild);        
     }
}

void midtravseTreap(Treap tree)
{
     midtravseTreapNode(tree->root);
}

void pretravseTreap(Treap tree)
{
     pretravseTreapNode(tree->root);
}

void destroyTreap(Treap tree)
{
     TreapLink x;
     for (x = tree->root; NULL != x; x = tree->root)
     {
           x = deleteTreap(tree, x->item);
           free(x);
     }
     free(tree);
}




 
2008-02-15 18:58:40 圈主 守住每一天 加为精华 引用回复
 提醒:您还不是程序设计的成员,您可以回复,但不能发表新帖。现在加入本圈与圈友无界沟通。
回复本贴
呢称: 
标题: 
内容: