Pagini recente » Cod sursa (job #3290678) | Cod sursa (job #2914918) | Cod sursa (job #2074022) | Cod sursa (job #994853) | Cod sursa (job #716265)
Cod sursa(job #716265)
#include<stdio.h>
#include<iostream>
#define subunitar 0.618 // aproximarea numarului sugerat de Donald Knuth
#define m 1048576 // pow(2,20)
#define POSITIVE(a) (a>=0) ? a : a+prim
#define prim 1000003
using namespace std;
FILE *in,*out;
typedef struct nod {int info;
nod *back,*next;}NOD; // folosesc liste liniare dublu inlantuite
NOD *v[m],*p,*r; // coliziunile se rezolva cu chaining
int a,b,x;
inline int hash(int x)
{
//return (int)( m * ( x*subunitar-(int)(x*subunitar) ) ); // functie hash bazata pe metoda inmultirii
//int position=(int)( m * ( x*subunitar-(int)(x*subunitar) ) );
//return position>=0 ? position : position+prim;
//return POSITIVE(position);
//return x%prim; // division method
return POSITIVE((x+(prim*3)/7)%prim); // Alqrainy's hash function , sursa: internet
}
void insert()
{
int k=0;
p=v[x];
while(p!=NULL&&k==0) // caut elementul b in lista v[x]
{
if(p->info==b)
k=1; // daca il gasesc,k devine 1 si se iese fortat din while
p=p->next; // se trece la urmatorul element al listei v[x]
}
if(k==0) // elementul care trebuie inserat nu se gaseste in hash
{
if(v[x]==NULL) // daca lista care incepe de la hash[x] e vida
{
v[x]=new NOD;
v[x]->info=b;
v[x]->next=NULL;
v[x]->back=NULL;
}
else
{
p=v[x];
while(p->next!=NULL)
p=p->next;
NOD *r;
r=new NOD;
r->info=b;
r->next=NULL;
r->back=p;
p->next=r;
}
}
}
void delete_value()
{
int k=0; // pointerul r este mereu cu un pas in urma lui p
p=v[x];
while(p!=NULL&&k==0)
{
if(p->info==b)
k=1;
r=p;
p=p->next;
}
if(k==1) // elementul care trebuie sters se gaseste in lista v[x]
{
if(r==v[x]) // daca elementul care trebuie sters este primul element din lista v[x]
{
NOD *s;
s=v[x]; // s memoreaza locatia primului element din lista v[x],care trebuie sters din memorie
v[x]=v[x]->next;
if(v[x]!=NULL) //verificam daca este unicul element al listei v[x],caz in care dupa eliminare,lista devine vida,v[x] fiind NULL
v[x]->back=NULL; // daca nu este singurul element al listei v[x],v[x]->back va deveni NULL
delete s; // eliberam memoria in care se afla elementul eliminat din lista
}
else
{
p=r->back; // p reprezinta elementul de inainte celui care trebuie sters
p->next=r->next; // schimbam legaturile
if(r->next!=NULL) // verificam daca elementul care trebuie sters este ultimul din lista v[x]
r->next->back=p;
delete r; // eliberam memoria in care se afla elementul eliminat din lista
}
}
}
void search_value() // cautam elementul b in lista v[x]
{
int k=0;
p=v[x];
while(p!=NULL&&k==0)
{
if(p->info==b) // daca gasim elementul b in lista v[x],k devine 1 si se iese din while
k=1;
p=p->next; // p pointeaza catre urmatorul element al liste v[x]
}
fprintf(out,"%d\n",k); // scriem in fisier valoarea lui k,1 daca s-a gasit in lista v[x],0 in caz contrar
}
int main()
{
int N,i,k; // N reprezinta numarul de comenzi din fisierul de intrare
in=fopen("hashuri.in","r");
out=fopen("hashuri.out","w");
fscanf(in,"%d",&N);
for(i=0;i<m;i++) // initializam hash-ul reprezentat de vectorul v cu NULL in fiecare pozitie
v[i]=NULL;
for(i=1;i<=N;i++)
{
fscanf(in,"%d %d",&a,&b); // a reprezinta tipul comenzii,b numarul citit
x=hash(b); // x reprezinta pozitia in cadrul hash-ului,v[x] fiind lista asociata
if(a==1)
insert();
else
if(a==2)
delete_value();
else
if(a==3)
search_value();
}
fclose(in);
fclose(out);
return 0;
}