Kod:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#define l 20
#define BOY 25
typedef struct Satir{//burada olusturdugumuz satir için alanlar tanımladık
int numara;
char ad[l];
char soyad[l];
struct Satir *sonraki;
struct Satir *onceki;
}Satirlar;
typedef struct table_{//burada da o satırları tabloya yerlestirmek için satır alanları açtık
Satirlar satirlar[BOY];
}Table;
Table table;//burda Table ı bir değişken tipi gibi kullandık.
void initialize_table(){//burada tablodaki satırların içini ilk başta boşalttık.
int i=0;
for(i=0;i<BOY;i++){//tüm alanları boşalttık
table.satirlar[i].numara=-1;//numara alnlarına -1 yazdık.
sprintf(table.satirlar[i].ad,"%s","bos");
sprintf(table.satirlar[i].soyad,"%s","bos");
table.satirlar[i].sonraki=NULL;
table.satirlar[i].onceki=NULL;
}
}
int hash(char *_ad,char *_soyad,int l_ad,int l_soyad){//burayada isimler ve soyadlar ve bunların boyutları geliyor
int i=0; int h=0; //isim ve soyadları ascii tabloya göre toplayıp ondan bir hash değeri elde ettik
//bu hash değerine görede tabloya yerleştireceğiz.
for(i=0;i<l_ad;i++){//mesela ali acar isminden 1 sayısını üretti diyelim onu numara bir olan yere yerleştireceğiz.
h+=_ad[i];
}
for(i=0;i<l_soyad;i++){
h+=(l_ad*_soyad[i]);
}
return h%BOY;//burada boya göre mod almamızın sebebi tabloda en fazla 25 boyut var 25 e göre mod alalımki 1 ile 25 arası
//bir sayı üretsin.böylece kişiler tablo aralığında olur
}
void collision(Satirlar *satir,Satirlar *isatir){//buradada mesela tabloya ayse ile ahmet isimleri geldi ve bunlar aynı hash değerlerini
while(isatir->sonraki!=NULL)//elde etti. o zaman bunların birini mi tabloya koycaz . tabikide hayır. ikisinide koyacaz.
isatir=isatir->sonraki;//ikisinide tabloya yerlestirmek için bağlı liste kullanıcaz. böylece aynı hash değeri üretenleri
isatir->sonraki=satir;//bağlı listeyle birbirine bağlayıp her ikisinede adım adım ulaşacağız. sadece ulaştığımız adım sayıları
satir->onceki=isatir;//farklı olacak.
satir->sonraki=NULL;
}
void ekle(char *_ad,char *_soyad){//burdada gelen kişileri tabloya ekliyoruz.
Satirlar *nsatir;
int hash_index=0;
hash_index=hash(_ad,_soyad,strlen(_ad),strlen(_soyad));//öncelikle hash fonksiyonundan gelen değeri hash_index e atadık.
//eğer hash den gelen değer boşsa ve hash den gelen değerdeki ad ile soyad tablodaki ad ile soyada eşitsedirek üstüne yaz.
if(table.satirlar[hash_index].numara==-1 || (strcmp(table.satirlar[hash_index].ad,_ad)==0&&strcmp(table.satirlar[hash_index].soyad,_soyad)==0) ){
table.satirlar[hash_index].numara=hash_index+1;
sprintf(table.satirlar[hash_index].ad,"%s",_ad);
sprintf(table.satirlar[hash_index].soyad,"%s",_soyad);
}
else{
nsatir=(Satirlar *)malloc(sizeof(Satirlar));//ama eğer isim soyad farklı olduğu halde aynı hash değerini üretiyorsa o zaman
nsatir->numara=hash_index+1;//bir satirlik yer açacağız bellekte bölece yeni gelen kaydı bağlı listeyle bağlıycaz aynı hash li değere
sprintf(nsatir->ad,"%s",_ad);
sprintf(nsatir->soyad,"%s",_soyad);
collision(nsatir,&table.satirlar[hash_index]);//bağlı listeyle bağlamak içinde collision fonk. çağırmamız lazım.
} //çünkü bağlama işlemini o fonksiyonun içinde yapmıştık.
}
void ara(char *_ad,char *_soyad){
int hash_index=0;
int sayi=1;
Satirlar *nsatir;
nsatir=(Satirlar *)malloc(sizeof(Satirlar));
//aramadada isim soyada göre aradığımız için önce bunuda hash fonk. yollayıp bi hash değeri üretmemiz lazım.
hash_index=hash(_ad,_soyad,strlen(_ad),strlen(_soyad));
//gelen hash deki değerdeki ad ve soyadlar tablodan biriyle aynıysa kaç adımda ulaştığını yazacaz.
if(strcmp(table.satirlar[hash_index].ad,_ad)==0 && strcmp(table.satirlar[hash_index].soyad,_soyad)==0)
printf("%d numarali ogrencinin kaydina %d adimda ulasildi\n",hash_index+1,sayi);
else{//öyle değilse bağlı listede varmı bakacak ordada yoksa bir sonraki satıra bakacak.ordada yoksa kayit bulunamadi diye msj verecek.
nsatir=table.satirlar[hash_index].sonraki;
while(nsatir){
sayi++;
if(strcmp(nsatir->ad,_ad)==0 && strcmp(nsatir->soyad,_soyad)==0){
printf("arama sonucu: %d numarali ogrencinin kaydina %d adimda ulasildi\n",nsatir->numara,sayi);
break;
}
else
nsatir=nsatir->sonraki;
}
}
printf("aranan kayit bulunamadi\n");
}
void listele(){
int i=0;
Satirlar *gecici;
for(i=0;i<BOY;i++){
if(table.satirlar[i].sonraki==NULL){//satırın sonraki NULL olana kadar bakacak.
printf("%d\t%s ",table.satirlar[i].numara,table.satirlar[i].ad);
printf("%s\n",table.satirlar[i].soyad);}
else{
printf("%d\t%s ",table.satirlar[i].numara,table.satirlar[i].ad);
printf("%s\n",table.satirlar[i].soyad);
gecici=table.satirlar[i].sonraki;
while(gecici!=NULL){//burdada bağlı liste içindekilerede bakacak onlarıda hash de aynı değeri paylaştıklarının
printf("- - - ->%s ",gecici->ad);//arkasına bağlı listeyle bağlayacak.yine bu da NULL olana kadar
printf("%s\n",gecici->soyad);
gecici=gecici->sonraki;
}
}//end else
}//end for
}//end listele
double hesapla(){
double ortalama=0,toplam=0;
int i=0,sayi=0,j=0;
Satirlar *nsatir;
nsatir = (Satirlar *)malloc(sizeof(Satirlar));
for(i=0;i<BOY;i++){
int rowsayi=1;
if(table.satirlar[i].numara!=-1){//if1
if(table.satirlar[i].sonraki==NULL){
toplam+=1;
sayi+=1;
}
else{
sayi++;
nsatir=table.satirlar[i].sonraki;
while(nsatir){
sayi++;
rowsayi++;
nsatir=nsatir->sonraki; }
for(j=1;j<=rowsayi;j++){
toplam+=j;
}
}//end else
}//end if1
else//if1
continue;
}//end for
printf("\nogrenci sayisi: %d,toplam: %3.2f\n",sayi,toplam);
ortalama=toplam/sayi;
return ortalama;
}//end hesapla
int main(){
FILE *ptdosya;
char adm[l],soyadm[l];
char secim=0;
char k = 0;
initialize_table();
ptdosya=fopen("C:/hash.txt","r");
if(ptdosya==NULL)
printf("dosya acilamadi\n");
else{
while (!feof(ptdosya)){
k = fgetc(ptdosya);
if (k == '\n' || ftell(ptdosya) == 1) {
if (ftell(ptdosya) == 1) rewind(ptdosya);
fscanf(ptdosya, "%s%s",adm,soyadm);
ekle(adm,soyadm);
}
}
fclose(ptdosya);
}
listele();
printf("\n");
printf("** programdan cikmak icin c yi\n""** arama yapmak icin a yi\n""** ortalama hesabi icin h yi tuslayin\n""** secim?\n");
while(secim!='c'){
printf("** ? ");
secim=getch();
switch(secim){
case 'a':printf("\naramak istediginiz kisinin ad ve soyadini giriniz\n");
scanf("%s%s",adm,soyadm);
ara(adm,soyadm);
break;
case 'h':printf("\ntablodaki elemanlara ortalama %3.2f adimda ulasilir\n",hesapla());
break;
case 'c':exit(0);
}
}
return 0;
}