zoukankan      html  css  js  c++  java
  • 实现跳表

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #define CASE_NUM 20000
      4 #define LEVEL 10
      5 
      6 struct Node 
      7 {
      8     int value;
      9     int level;
     10     struct Node* down_p;
     11     struct Node* next;
     12 };
     13 
     14 struct Node* init_skip_list(int level)
     15 {
     16     int i;
     17 
     18     struct Node* NodeList[level];
     19     for(i=0; i<level; ++i)
     20     {
     21         NodeList[i] = (struct Node*)malloc(sizeof(struct Node));
     22         NodeList[i]->next = NULL;
     23         NodeList[i]->value = 0;
     24         NodeList[i]->level = i+1;
     25         if(i>0)
     26         {
     27             NodeList[i]->down_p = NodeList[i-1];
     28             printf("build down forward, level=%d
    ", i+1);
     29         } 
     30         else 
     31         {
     32             NodeList[i]->down_p = NULL;
     33         }
     34     }
     35     return NodeList[level-1];
     36 }
     37 
     38 int get_rand_level(int level)
     39 {
     40     int value_level = 1;
     41     while(rand()%2) value_level ++;
     42     if(value_level > level) value_level = level;
     43     return value_level;
     44 }
     45 
     46 int insert_number(int value, struct Node* node, int level)
     47 {
     48     int value_level;
     49     int i;
     50     int cost_step = 0;
     51     value_level = get_rand_level(level);
     52 
     53     struct Node* NodeList[level];
     54     int level_run[level];
     55 
     56     for(i=0; i<level; ++i) level_run[i] = 0;
     57 
     58     struct Node* tmp; // temp storage node
     59     tmp = NULL;
     60     int insert = 0;
     61     while(node != NULL)
     62     {
     63         insert = node->level <= value_level ? 1 : 0;
     64 
     65         struct Node* new_node;
     66         new_node = (struct Node*)malloc(sizeof(struct Node));
     67         new_node->value = value;
     68         new_node->level = node->level;
     69         new_node->down_p = NULL;
     70 
     71         while(1)
     72         {
     73             if(node->next && node->next->value < value)
     74             {
     75                 node = node->next;
     76                 cost_step ++;
     77                 level_run[node->level-1] ++;
     78             } 
     79             else
     80             {
     81                 if(insert)
     82                 {
     83                     new_node->next = node->next;
     84                     node->next = new_node;
     85                     if(tmp != NULL)
     86                     {
     87                         tmp->down_p = new_node;
     88                     }
     89                     tmp = new_node;
     90                 }
     91                 /*
     92                 else
     93                 {
     94                     printf("Now level is %d, need create under %d level
    ",
     95                             node->level, value_level);
     96                 }
     97                 */
     98                 //printf("Success insert new node, value=%d, level=%d
    ",
     99                 //        value, i+1);
    100                 break;
    101             }
    102         }
    103         node = node->down_p;
    104     }
    105     /* DEBUG PIRNT
    106     printf("---- value %d cost step ----
    ", value);
    107     for(i=0; i<level; ++i)
    108     {
    109         printf("level %d cost step %d
    ", i+1, level_run[i]);
    110     }
    111     */
    112     return cost_step;
    113 }
    114 
    115 int find_number(int value, struct Node* node)
    116 {
    117     int i;
    118     int find = 0;
    119     int cost_step = 0;
    120     while(node != NULL)
    121     {
    122         //printf("node->value=%d, node->level=%d, node->down_p=%p, node->next=%p
    ", 
    123         //        node->value, node->level, node->down_p, node->next);
    124         while(node->next && node->next->value<=value)
    125         {
    126             //printf("step forward one step
    ");
    127             node = node->next;
    128             cost_step ++;
    129         }
    130         if(node->value == value)
    131         {
    132             find = 1;
    133             break;
    134         }
    135         //printf("node->down_p->value=%d, node->down_p->level=%d, node->down_p->down_p=%p
    ",
    136         //        node->down_p->value, node->down_p->level, node->down_p->down_p);
    137         node = node->down_p;
    138         cost_step ++;
    139     }
    140     //printf("find %d cost step %d
    ", value, cost_step);
    141     if(find!=1)
    142     {
    143         printf("Warning, error occured, value=%d
    ", value);
    144     }
    145     return cost_step;
    146 }
    147 
    148 void show_skip_list(struct Node* node, int level)
    149 {
    150     int i;
    151     struct Node* NodeList[level];
    152     struct Node* p;
    153     int NodeCnt[level];
    154     for(i=0; i<level; ++i)
    155     {
    156         NodeList[level-i-1] = node;
    157         node = node->down_p;
    158         NodeCnt[i] = 0;
    159     }
    160 
    161     for(i=level-1; i>=0; --i)
    162     {
    163         int sign = 0;
    164         p = NodeList[i];
    165         while(p)
    166         {
    167             /*
    168             if(sign)
    169             {
    170                 printf(" -> %d", p->value);
    171             }
    172             else
    173             {
    174                 printf("%d", p->value);
    175             }
    176             */
    177             sign = 1;
    178             NodeCnt[i] ++;
    179             p = p->next;
    180         }
    181         //printf("
    ");
    182     }
    183     for(i=0; i<level; ++i) printf("level %d cnt %d
    ", i+1, NodeCnt[i]);
    184     return;
    185 }
    186 
    187 int main()
    188 {
    189     int level = LEVEL;
    190     int res;
    191     int i;
    192     int tmp;
    193     struct Node* p;
    194     p = init_skip_list(level);
    195 
    196     int test_data[CASE_NUM];
    197     long long total_insert_cost_step = 0;
    198     int one_time;
    199     
    200     for(i=0; i<CASE_NUM; i++)
    201     {
    202         tmp = rand()%1000000;
    203         test_data[i] = tmp;
    204         one_time = insert_number(tmp, p, level);
    205         total_insert_cost_step += one_time;
    206         //printf("inserting %d cost %d step
    ", tmp, one_time);
    207     }
    208     printf("insert average cost %lld step
    ", total_insert_cost_step/CASE_NUM);
    209     printf("Begin show_skip_list
    ");
    210     show_skip_list(p, level);
    211     int total_cost_step = 0;
    212     for(i=0;i<CASE_NUM;i++)
    213     {
    214         tmp = test_data[i];
    215         res = find_number(tmp, p);
    216         total_cost_step += res;
    217     }
    218     printf("Average cost %d step
    ", total_cost_step/CASE_NUM);
    219     return 0;
    220 }

    自己手写了一下跳表,加深了对跳表的理解,贴一下代码

    输出

    insert average cost 21 step
    Begin show_skip_list
    level 1 cnt 20001
    level 2 cnt 10031
    level 3 cnt 5087
    level 4 cnt 2567
    level 5 cnt 1333
    level 6 cnt 704
    level 7 cnt 367
    level 8 cnt 191
    level 9 cnt 95
    level 10 cnt 51
    Average cost 40 step

    相比较之下,python的heapq插入速度明显比我实现的这个跳表快很多,这点我需要研究一下。看看为啥我这个这么慢

  • 相关阅读:
    Apache Commons介绍(转载)
    MYSQL Nested Join Optimization
    Mysql Nested-Loop Join Algorithms
    jquery eval解析JSON中的注意点介绍
    jspSmartUpload上传下载使用例子
    JavaWeb基础
    (一)Model的产生及处理
    SpringMVC注解@RequestParam全面解析
    @ModelAttribute使用详解
    Spring中Controller和RequestMapping的详解
  • 原文地址:https://www.cnblogs.com/symons1992/p/8719418.html
Copyright © 2011-2022 走看看