Pagini recente » Cod sursa (job #1674071) | Cod sursa (job #1025079) | Cod sursa (job #563568) | Cod sursa (job #235912) | Cod sursa (job #719732)
Cod sursa(job #719732)
#include<cstdio>
#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 // pentru a afla pozitia in cadrul hash-ului a numerelor negative
#define prim 1000003
using namespace std;
class Hash
{
typedef struct nod {int info;
nod* back;
nod* next;}NOD; // folosesc liste liniare dublu inlantuite // coliziunile se rezolva cu chaining
typedef NOD* PNOD;
PNOD *v,p,r;
public:
Hash();
inline int h(const int&);
bool search_value(const int&);
bool insert(const int&);
bool delete_value(const int&);
~Hash();
};
Hash::Hash() // constructor
{
v=new PNOD[prim];
for(int i=0;i<prim;i++) // initializam hash-ul reprezentat de vectorul v cu NULL in fiecare pozitie
v[i]=NULL;
}
inline int Hash::h(const int& value) // returneaza pozitia in cadrul vectorului v
{
//return (int)( m * ( value*subunitar-(int)(value*subunitar) ) ); // functie hash bazata pe metoda inmultirii
//return value%prim; // division method
return (value+(prim*3)/7)%prim; // Alqrainy's hash function , sursa: internet
}
bool Hash::search_value(const int& value) // cautam elementul b in lista v[x]
{
register int x,k=0;
x=h(value); // x reprezinta pozitia in cadrul hash-ului,v[x] fiind lista asociata
p=v[x];
while(p!=NULL&&k==0)
{
if(p->info==value) // daca gasim elementul b in lista v[x],k devine 1 si se iese din while
k=1;
r=p; // la cautarea cu succes,p este cu un pas in fata la iesire din bucla,iar r memoreaza adresa corecta,fiind cu un pas in urma lui p
p=p->next; // p pointeaza catre urmatorul element al liste v[x]
}
return k;
}
bool Hash::insert(const int& value) // returneaza 1 daca s-a facut inserarea,elementul nu se afla deja in hash,si 0 daca inserarea nu a avut loc,adica elementul se afla deja in hash
{
register int x=h(value); // x reprezinta pozitia in cadrul hash-ului,v[x] fiind lista asociata
p=v[x];
if(search_value(value)==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=value;
v[x]->next=NULL;
v[x]->back=NULL;
}
else
{
p=v[x];
while(p->next!=NULL)
p=p->next;
r=new NOD;
r->info=value;
r->next=NULL;
r->back=p;
p->next=r;
}
return 1;
}
return 0;
}
bool Hash::delete_value(const int& value) // returneaza 1 daca elementul s-a gasit in hash si s-a sters,returneaza 0 daca elementul nu este in hash
{
register int x=h(value);
p=v[x];
if(search_value(value)==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]
{
PNOD 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
}
return 1;
}
return 0;
}
Hash::~Hash() // destructor in care sterg din memorie vectorul v,care a fost alocat dinamic cu new
{
delete [] v;
}
int main()
{
Hash H; // H este un obiect al clasei Hash
register int N,i,a,b; // N reprezinta numarul de comenzi din fisierul de intrare
FILE *in,*out;
in=fopen("hashuri.in","r");
out=fopen("hashuri.out","w");
fscanf(in,"%d",&N);
for(i=1;i<=N;i++)
{
fscanf(in,"%d %d",&a,&b); // a reprezinta tipul comenzii,b numarul citit
if(a==1)
H.insert(b);
else
if(a==2)
H.delete_value(b);
else
if(a==3)
fprintf(out,"%d\n",H.search_value(b));
}
fclose(in);
fclose(out);
return 0;
}