Titlul: skiplists
Scris de: alexjj din Februarie 08, 2005, 09:58:00
in struct nod {} , in loc de nod * link n-ar trebui sa fie nod ** link ? avem nevoie de mai multi pointeri din fiecare nod ...
Titlul: skiplists
Scris de: Dan-Leonard Crestez din Februarie 08, 2005, 15:21:46
Da, asa este, e nevoie de nod** link, am modificat. Codul asta oricum nu compileaza in C pur, acolo trebuie ceva de genul:
typedef struct _node_ node; struct _node_ { // whatever }
Pasajele cu cod sursa din articole sunt prezentate orientativ, nu va asteptati sa fie 100% corect, nici macar sa compileze.
Oricum, multumesc de comentariu, orice fel de feed-back cu privire la articole e bine venit.
Titlul: skiplists
Scris de: alexjj din Februarie 10, 2005, 20:11:42
ma bucur ca am putut ajuta :D . am incercat sa implementez shi am intampinat probleme. am facut ceva de genu struct nod {int key; nod ** next;};
shi alocarea x->next= new nod* [nr_de_pointeri_necesari]. algoritmul e bun (am mai cautat pa net shi am gasit documente mult mai detaliate.) dar din motive necunoscute (l-am rulat shi lam depanat in draci) nu functioneaza totdeauna k lumea. (other) ideas/help for implementation ? :(
Titlul: skiplists
Scris de: Giurgea Mihnea din Februarie 21, 2005, 13:06:04
Mi se parea destul de important sa se explice si adaugarea efectiva, dar ma rog e inuitiv. Ceea ce nu inteleg este nod** link. Poate cineva sa-mi explice adaugarea / sami trimita o sursa care merge pe mail. Daca aveti, va rog datimi shi mie pe [email protected]
Titlul: skiplists
Scris de: Mircea Pasoi din Februarie 21, 2005, 20:44:36
hei... sa bage careva sursa aia jmenoasa a lu` Berinde cu skiplists. 8) 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 :wink: .. 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. :D /* 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; }
Titlul: skiplists
Scris de: Cristian Strat din Februarie 21, 2005, 20:50:57
lol agitate vremuri ...
Titlul: skiplists
Scris de: Mircea Pasoi din Februarie 21, 2005, 20:51:08
Am mai gasit o sursa de skiplist, ceva mai "didactic" scrisa.. Here it is: /* skip list */
#include <stdio.h> #include <stdlib.h>
/* implementation dependend declarations */ typedef enum { STATUS_OK, STATUS_MEM_EXHAUSTED, STATUS_DUPLICATE_KEY, STATUS_KEY_NOT_FOUND } statusEnum;
typedef int keyType; /* type of key */
/* user data stored in tree */ typedef struct { int stuff; /* optional related data */ } recType;
#define compLT(a,b) (a < b) #define compEQ(a,b) (a == b)
/* levels range from (0 .. MAXLEVEL) */ #define MAXLEVEL 15
typedef struct nodeTag { keyType key; /* key used for searching */ recType rec; /* user data */ struct nodeTag *forward[1]; /* skip list forward pointer */ } nodeType;
/* implementation independent declarations */ typedef struct { nodeType *hdr; /* list Header */ int listLevel; /* current level of list */ } SkipList;
SkipList list; /* skip list information */
#define NIL list.hdr
statusEnum insert(keyType key, recType *rec) { int i, newLevel; nodeType *update[MAXLEVEL+1]; nodeType *x;
/*********************************************** * allocate node for data and insert in list * ***********************************************/
/* find where key belongs */ x = list.hdr; for (i = list.listLevel; i >= 0; i--) { while (x->forward[i] != NIL && compLT(x->forward[i]->key, key)) x = x->forward[i]; update[i] = x; } x = x->forward[0]; if (x != NIL && compEQ(x->key, key)) return STATUS_DUPLICATE_KEY;
/* determine level */ for ( newLevel = 0; rand() < RAND_MAX/2 && newLevel < MAXLEVEL; newLevel++);
if (newLevel > list.listLevel) { for (i = list.listLevel+1; i<=newLevel; i++) update[i] = NIL; list.listLevel = newLevel; }
/* make new node */ if ((x = malloc(sizeof(nodeType) + newLevel *sizeof(nodeType *))) == 0) return STATUS_MEM_EXHAUSTED; x->key = key; x->rec = *rec;
/* update forward links */ for (i = 0; i <= newLevel; i++) { x->forward[i] = update[i]->forward[i]; update[i]->forward[i] = x; } return STATUS_OK; }
statusEnum delete(keyType key) { int i; nodeType *update[MAXLEVEL+1], *x;
/******************************************* * delete node containing data from list * *******************************************/
/* find where data belongs */ x = list.hdr; for (i = list.listLevel; i >= 0; i--) { while (x->forward[i] != NIL && compLT(x->forward[i]->key, key)) x = x->forward[i]; update[i] = x; } x = x->forward[0]; if (x == NIL || !compEQ(x->key, key)) return STATUS_KEY_NOT_FOUND;
/* adjust forward pointers */ for (i = 0; i <= list.listLevel; i++) { if (update[i]->forward[i] != x) break; update[i]->forward[i] = x->forward[i]; }
free (x);
/* adjust header level */ while ((list.listLevel > 0) && (list.hdr->forward[list.listLevel] == NIL)) list.listLevel--;
return STATUS_OK; }
statusEnum find(keyType key, recType *rec) { int i; nodeType *x = list.hdr;
/******************************* * find node containing data * *******************************/
for (i = list.listLevel; i >= 0; i--) { while (x->forward[i] != NIL && compLT(x->forward[i]->key, key)) x = x->forward[i]; } x = x->forward[0]; if (x != NIL && compEQ(x->key, key)) { *rec = x->rec; return STATUS_OK; } return STATUS_KEY_NOT_FOUND; }
void initList() { int i;
/************************** * initialize skip list * **************************/
if ((list.hdr = malloc( sizeof(nodeType) + MAXLEVEL* sizeof(nodeType *))) == 0) { printf ("insufficient memory (initList)\n"); exit(1); } for (i = 0; i <= MAXLEVEL; i++) list.hdr->forward[i] = NIL; list.listLevel = 0; }
int main(int argc, char **argv) { int i, maxnum, random; recType *rec; keyType *key; statusEnum status;
/* command-line: * * skl maxnum [random] * * skl 2000 * process 2000 sequential records * skl 4000 r * process 4000 random records * */
maxnum = atoi(argv[1]); random = argc > 2;
initList();
if ((rec = malloc(maxnum * sizeof(recType))) == 0) { fprintf (stderr, "insufficient memory (rec)\n"); exit(1); } if ((key = malloc(maxnum * sizeof(keyType))) == 0) { fprintf (stderr, "insufficient memory (key)\n"); exit(1); }
if (random) { /* fill "a" with unique random numbers */ for (i = 0; i < maxnum; i++) key[i] = rand(); printf ("ran, %d items\n", maxnum); } else { for (i = 0; i < maxnum; i++) key[i] = i; printf ("seq, %d items\n", maxnum); }
for (i = 0; i < maxnum; i++) { status = insert(key[i], &rec[i]); if (status) printf("pt1: error = %d\n", status); }
for (i = maxnum-1; i >= 0; i--) { status = find(key[i], &rec[i]); if (status) printf("pt2: error = %d\n", status); }
for (i = maxnum-1; i >= 0; i--) { status = delete(key[i]); if (status) printf("pt3: error = %d\n", status); } return 0; }
Titlul: Răspuns: skiplists
Scris de: Stefan Istrate din Februarie 20, 2009, 02:35:59
Discutia poate continua in topicul destinat acestui articol: http://infoarena.ro/forum/index.php?topic=3688.0
|