hei... sa bage careva sursa aia jmenoasa a lu` Berinde cu skiplists.
eu nu o am la indemana.
Nu cred ca exista asa ceva, din cate stiu eu Berinde n-a facut niciodata skiplisturi ... cred ca era vorba de sursa ta
.. ma rog, eu am o sursa de a ta, modifica un pic de Silviu cred, o atasez mai jos pentru toti, sper sa fie 100% corecta. Daca are o varianta mai recenta il rog pe Silviu sa o puna aici.
/*
Skip List
inserare, stergere, cautare: O(lgN)
>> sursa facuta cu tab-size 4 <<
* inserarea si cautarea merg de minune insa *stergerea* merge greu
atunci
cand te apuci sa stergi elementele in ordine, altfel, pe cazuri
random,
merge bine. totusi am vazut niste grafice cu timpi de executie
skip lists VS AVL (de mai multe feluri) si skip list-urile mergeau
mai
bine la toate operatiile (inclusiv stergere).
* pentru cazuri in care nu ai nevoie de stergeri sunt super
bestiale
skip list-urile: usor de implementat (rapid si greu de gresit), mai
rapide si mai putina memorie
* pentru cazuri in care ai nevoie de stergere, risti cu o constanta
mare
cand se intampla sa stergi multe in ordine
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
/* o chestie de probabilistica. merge bine 2, 4 */
#define L_P 2
/* nr. maxim de nivele. in general trebuie luat log(L_P,
MAX_ELEMENTE) */
#define L_MAXL 16
/* valoare mai mare decat orice cheie din lista */
#define L_INF 10000000
struct elem {
int key;
struct elem *fw[1];
};
typedef struct elem elem;
elem *H, *NIL, *aux[L_MAXL];
/* in ll se retine nivelul curent al listei. teoretic nu avem nevoie de
ll
intrucat putem considera nivelul listei ca fiind L_MAXL. insa cu
ajutorul
lui ll se pot face niste optimizari sesizabile (constante) */
int ll;
/* pentru teste */
#define MAXT 1000013
char T[MAXT];
/* /pentru teste */
void linit() {
int i;
/* aici se mai poate simplifica dar fac asa ca sa KISS */
NIL=(elem *)malloc(sizeof(elem)+sizeof(elem *)*L_MAXL);
H=(elem *)malloc(sizeof(elem)+sizeof(elem *)*L_MAXL);
H->key=NIL->key=L_INF;
for (ll=i=0; i<L_MAXL; i++) H->fw[i]=NIL->fw[i]=NIL;
}
elem *lsearch(int key) {
elem *e;
int i;
for (i=ll-1, e=H; i>=0; i--)
for (; e->fw[i]->key<key; e=e->fw[i]);
return (e->fw[0]->key==key?e->fw[0]:NULL);
}
elem *ladd(int key) {
elem *e;
int i, nl;
/* determina locatie */
for (i=ll-1, e=H; i>=0; aux[i--]=e)
for (; e->fw[i]->key<key; e=e->fw[i]);
if (e->fw[0]->key==key) return e->fw[0];
/* nod nou */
for (nl=1; rand()<RAND_MAX/L_P && nl<L_MAXL; nl++);
e=(elem *)malloc(sizeof(elem)+sizeof(elem *)*nl);
assert(e);
e->key=key;
for (i=0; i<nl; i++) {
if (i<ll) e->fw[i]=aux[i]->fw[i], aux[i]->fw[i]=e;
else H->fw[i]=e, e->fw[i]=NIL;
}
if (nl>ll) ll=nl;
return e;
}
char ldel(int key) {
int i;
elem *e;
/* determina locatie */
for (i=ll-1, e=H; i>=0; aux[i--]=e)
for (; e->fw[i]->key<key; e=e->fw[i]);
e=e->fw[0];
if (e->key!=key) return 0;
/* repara pointeri */
for (i=0; i<ll && aux[i]->fw[i]==e; aux[i]->fw[i]=e->fw[i++]);
free(e);
/* repara ll */
for (; ll && H->fw[ll-1]==NIL; ll--);
return 1;
}
int main(void)
{
FILE *fin, *fout;
char c; int x;
elem *e;
fin = fopen("in.txt", "r");
fout = fopen("out.txt", "w");
linit();
while (!feof(fin))
{
fscanf(fin, "%c %d\n", &c, &x);
if (c == 'I')
ladd(x);
else
if (c == 'S')
fprintf(fout, "search for %d: %d\n", x, lsearch(x) != NULL);
else
if (c == 'E')
ldel(x);
}
fclose(fin), fclose(fout);
return 0;
}