Chinaunix首页 | 论坛 | 博客
  • 博客访问: 126162
  • 博文数量: 36
  • 博客积分: 94
  • 博客等级: 民兵
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-23 17:34
文章分类
文章存档

2015年(1)

2013年(7)

2012年(3)

2011年(25)

分类:

2011-08-26 14:35:54


这个版本改进了功能
1允许重复元素插入,维护一个字段 weight,如果weight >1 ,表示存在重复元素。
   /*尽量不要用重复插入,因为有date字段*/
2 增添了floor 和ceil两个功能,顾名思义,就是key值不大于 A的最大元素,和K值不小于A的最小元素
3 选择第K个最小关键字的元素。0表示最小关键字,1表示第二小关键字。

--------------------------------------------------------------------------------------------------
#ifndef _TREAP_H
#define _TREAP_H

typedef int  key_type ;
typedef unsigned int  prio_type;

typedef struct _treap_node
{
struct _treap_node *left;
struct _treap_node *right;
key_type key;
prio_type priority;
int size;
int weight;
int data;

}treap_node;

typedef struct _treap
{
treap_node* root;
}treap;

treap_node* treap_insert(treap_node* root,int key,int data);
treap_node* treap_delete(treap_node* root,int key);
treap_node* treap_floor(treap_node *root,key_type key);
treap_node* treap_ceil(treap_node* root,key_type key);
treap_node* treap_select(treap_node* root,int K); /*0 is the min element*/

#endif
--------------------------------treap.c-----------------------------------------------------------
#include
#include"treap.h"
#include
#include
#include"treap.h"

#define lsize(node) (node->left?node->left->size:0)
#define rsize(node) (node->right?node->right->size:0)

treap_node*  treap_left_rotate(treap_node *node)
{
assert(node->right != NULL);
treap_node* right = node->right;
int original_nodesize = node->size;
node->size =  lsize(node) + lsize(right) +node->weight;
right->size = original_nodesize;
node->right = right->left;
right->left = node;
return  right;
}

treap_node* treap_right_rotate(treap_node* node)
{
assert(node->left !=NULL);

treap_node* left = node->left;
int original_nodesize = node->size;
node->size = rsize(node)+ rsize(left) + node->weight;
left->size = original_nodesize;
node->left = left->right;
left->right = node;

return left;
}


treap_node* treap_allocnode(key_type key,int data)
{
treap_node* node = NULL;
node = (treap_node*)malloc(sizeof(treap_node));
if(node == NULL)
return NULL;
else
{
node->left = node->right = NULL;
node->key = key;
node->data = data;
node->priority = rand()*rand();
node->size = 1; /*节点个数*/
node->weight = 1;
return node;
}
}

void treap_freenode(treap_node* node)
{
      if(node)
          free(node);
}
treap_node* __treap_insert(treap_node* root,key_type  key,int data,unsigned char *isinsert)
{
if(root == NULL)
{
treap_node *new_node = treap_allocnode(key,data);
*isinsert = 1;
return new_node;
}

if(root->key == key)
{
#if 0      /*如果不允许重复,直接返回*/
return root;
#endif
root->weight++;  
      *isinsert = 1;
return root;   /*允许重复,weight++即可*/
}
if(root->key > key)
{
root->left = __treap_insert(root->left,key,data,isinsert);
if(*isinsert == 1)
root->size ++;
if(root->left->priority < root->priority)
return treap_right_rotate(root);
else
return root;
}
if(root->key < key)
{
root->right = __treap_insert(root->right,key,data);
if(*isinsert == 1)
root->size++;
if(root->right->priority < root->priority)
return treap_left_rotate(root);
else
return root;
}
}

treap_node* treap_insert(treap_node* root,key_type key,int data)
{
unsigned char isinsert =0;
return __treap_insert(root,key,data,&isinsert);
}
treap_node* __treap_delete(treap_node* root,key_type key,unsigned char *isfind)
{
    
    if(root == NULL)
    {
    *isfind = 0;
    return NULL;/*not find a element with key equal to key*/
    }
    if(root->key == key)
    {

      *isfind = 1;
      
      if(root->weight == 1)
      {
           
            if(root->left == NULL || root->right == NULL)
            {
                 treap_node* delnode =root;
                 if(root->left == NULL)
                      root = root->right;
                 else
                      root = root->left;
        
                 treap_freenode(delnode);
                 return root;            
          }
          else
          {
                if(root->left->priority < root->right->priority)
                {
                     treap_node* retnode = root->left;
                     treap_right_rotate(root);
                     retnode->right = __treap_delete(root,key,isfind);
       if(isfind)
                 retnode->size--;
                     return retnode;
                }
               else
               {
                    treap_node* retnode = root->right;
                    treap_left_rotate(root);
                    retnode->left = __treap_delete(root,key,isfind);
if(isfind)
                retnode->size--;
                    return retnode;
               }
         }
     }
      else 
      {
        root->weight--;
       return root;
      }
     
    }
    else
    {
         if(root->key < key)
         {
            root->right = __treap_delete(root->right,key,isfind);
if(*isfind == 1)
           root->size--;
         }
         else
         {
            root->left = __treap_delete(root->left,key,isfind);
if(*isfind)
       root->size--;
         }

         return root;
    }
    
}


treap_node* treap_delete(treap_node *root,key_type key)
{
  unsigned char isfind = 0;
return __treap_delete(root,key,&isfind);
}

treap_node*  __treap_floor(treap_node* node,key_type key,treap_node* optimal)
{
if(node == NULL )
  {
        return optimal;
}

if(node->key == key)
        {
 return node; /*及时终止,毕竟压栈弹栈耗费性能*/
}
if(node->key <  key)
{
              return __treap_floor(node->right,key,node);/* third parameter means  node is current optimal*/
}
else
        {
              return __treap_floor(node->left,key,optimal);
}
 
}

treap_node* __treap_ceil(treap_node* node ,key_type key,treap_node* optimal)
{
if(node == NULL)
{
return optimal;
}

if(node->key == key)
{
return node;        /*及时终止,毕竟压栈弹栈耗费性能*/
}
if(node->key > key)
{
return __treap_ceil(node->left,key,node);
                /*third para means node is current optimal*/
}
else
{
return __treap_ceil(node->right,key,optimal);
}
}
treap_node* treap_floor(treap_node *root,key_type key)
{
return __treap_floor(root,key,NULL);
}

treap_node* treap_ceil(treap_node* root,key_type key)
{
return __treap_ceil(root, key,NULL);
}

treap_node* treap_select(treap_node* root,int K) /*0 is the min element*/
{
  if(root == NULL)
     return NULL;
  if(K < lsize(root))
     return treap_select(root->left,K);
  
  else if(K >lsize(root) + root->weight)
     return treap_select(root->right,K - (lsize(root)+root->weight));
  else  
     return root;
      
}


-----------------------------treap_test.c-----------------------------------------------------------
#include
#include
#include
#include"treap.h"
#define NODE_NUM 10
#define random(x) (rand()%x)
void test_treap()
{
  int i;
  treap_node* floor = NULL;
  treap_node* mid = NULL;
  int array_random[NODE_NUM] ;
  for(i = 0;i
{
   array_random[i] = random(10000);
printf("array_random[%d] = %d\n",i,array_random[i]);
}
  
  treap my_treap;
  my_treap.root = NULL;
  
  for(i = 0;i
  {
    my_treap.root = treap_insert(my_treap.root,array_random[i],array_random[i]);
  }

  floor = treap_floor(my_treap.root, 5000);
  if(floor)
  printf("the biggest node biger than 5000 is %d\n",floor->key);
  
  mid = treap_select(my_treap.root,my_treap.root->size/2);
  if(mid)
  printf("the mid is %d\n",mid->key);
  
}


int main()
{
  test_treap();
  return 0;
}
阅读(1007) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~