AVL木(mallocなし版)
C言語でmapが必要になったときのためのライブラリ。
mallocが遅いだろうと思って、
spaghetti sourceのAVL木をmallocを使わずに書き換えたもの。
ソースコード
#include<stdio.h> #include<string.h> /* AVL木によるmapの実装 spaghetti sourceの移植だけど、mallocなし版 */ #define S int #define T int #define MAX_SIZE 2000000 typedef struct{ S key; T value; int size, height; int child[2]; } node; node list[MAX_SIZE]; int size; int balance(int); int cmp(const void *a, const void *b){ return *((int*)a) - *((int*)b); } #define max(a, b) (a > b ? a : b) #define sz(t) (t ? list[t].size : 0) #define ht(t) (t ? list[t].height : 0) int rotate(int t, int l,int r){ int s = list[t].child[r]; list[t].child[r] = list[s].child[l]; list[s].child[l] = balance(t); if(t)list[t].size = sz(list[t].child[0]) + sz(list[t].child[1]) + 1; if(s)list[s].size = sz(list[s].child[0]) + sz(list[s].child[1]) + 1; return balance(s); } int balance(int t){ int i; for(i = 0; i < 2; i++){ if(ht(list[t].child[!i]) - ht(list[t].child[i]) < -1){ if(ht(list[list[t].child[i]].child[!i]) - ht(list[list[t].child[i]].child[i]) > 0) list[t].child[i] = rotate(list[t].child[i], i, !i); return rotate(t, !i, i); } } if(t)list[t].height = max(ht(list[t].child[0]), ht(list[t].child[1])) + 1; if(t)list[t].size = sz(list[t].child[0]) + sz(list[t].child[1]) + 1; return t; } int move_down(int t,int rhs){ if(t == 0)return rhs; list[t].child[1] = move_down(list[t].child[1], rhs); return balance(t); } int find(int t, const S* key){ if(t == 0)return 0; int res = cmp(key, &list[t].key); if(res == 0)return t; if(res < 0) return find(list[t].child[0], key); return find(list[t].child[1], key); } int erase(int t, const S* key){ if(t == 0)return 0; int res = cmp(key, &list[t].key); if(res == 0)return move_down(list[t].child[0], list[t].child[1]); if(res < 0)list[t].child[0] = erase(list[t].child[0], key); else list[t].child[1] = erase(list[t].child[1], key); list[t].size--; return balance(t); } int insert2(int t, int x){ if(t == 0)return x; if(cmp(&list[x].key, &list[t].key) <= 0)list[t].child[0] = insert2(list[t].child[0], x); else list[t].child[1] = insert2(list[t].child[1], x); list[t].size++; return balance(t); } int insert(int root, const S* key, const T* value){ ++size; list[size].size = list[size].height = 1; memcpy(&list[size].key, key, sizeof(S)); memcpy(&list[size].value, value, sizeof(T)); return insert2(root, size); } int rank(int t, int k){ if(!t)return 0; int m = sz(list[t].child[0]); if(k < m)return rank(list[t].child[0], k); if(k == m)return t; return rank(list[t].child[1], k-m-1); }
速度
5〜10%くらい遅くなった。なんでやねん!!
verify
TopCode SRM 310 Div1 Medium