2
Nis'11

C’de Bağlı Liste İle Kayıt Fonksiyonları (C Programlama Dili)

Bağlı liste, stack ve kuyruk konularına daha önce bir açıklık getirmeye çalışmıştım.Konu anlatımına buradan ulaşabilirsiniz.

Şimdi ise çift yönlü bağlı liste mantığını ve dinamik bellek adresleme yöntemlerinden malloc fonksiyonunu kullanarak kayit ekleme,listeleme,arama,silme,güncelleme fonksiyonlarını paylaşacağım.Program içinde yorum satırlarını iyi kullanmaya gayret ettim.

İlk önce kayıtların tutulacağı struct veri yapısını tanımlamak gerekiyor;

struct Kayit{
    char isim[20];
    Kayit *sonraki, *onceki;
};
struct Kayit *ilk, *son, *gecici;

Şimdi bu struct yapısını baz alarak fonksiyonları yazmaya başlayabiliriz.
Kayıt ekleyerek başlayalım;

void Ekle(){

printf("Isim Giriniz : ");

if(ilk==NULL){// ilk kayitsa

ilk = (Kayit *) malloc(sizeof(struct Kayit));
fflush(stdin); gets(ilk->isim);
ilk->sonraki = NULL;
ilk->onceki = NULL;//ikinci bağ.
son = ilk;
}

else if(son == ilk){// ikinci kayitsa

son = (Kayit *) malloc(sizeof(struct Kayit));
fflush(stdin); gets(son->isim);
ilk->sonraki = son;
son->sonraki = NULL;
son->onceki = ilk;//ikinci bağ.
}

else{// ikiden fazla kayıt varsa

gecici = (Kayit *) malloc(sizeof(struct Kayit));
fflush(stdin); gets(gecici->isim);
son->sonraki = gecici;
gecici->onceki = son;//bu iki satırda gecici sona eklendi.
////////////////
son = gecici;
son->sonraki = NULL;//bu iki satırda da son işaretçisi son gelen veriye aktarıldı.
}
}

Eklediğimiz kayıtları listeleyelim!

Kayıtları eklerken çift yölü olarak ekledik.Listelerkende hem baştan sona hemde sondan başa listelesin.

void Listele(){

gecici = ilk;

printf("\n--Birinci Gosterim--\n\n");

while(gecici != NULL){

printf("\t%s\n", gecici->isim);
gecici = gecici->sonraki;
}

gecici = son;

printf("\n--Ikinci Gosterim--\n\n");

while(gecici != NULL){

printf("\t%s\n", gecici->isim);
gecici = gecici->onceki;
}
}

Şimdi ise kayıtlar arasında arama yapmak lazım.

Kullanıcıdan aranacak olan ismi alıp, bulduktan sonra gecici diye tanımladığımız struct işaretçisinin aranan kaydı aklında tutmasını sağlarız.

void Ara(){

char aranan_isim[20];

printf("\n\Guncellenecek,Aranacak ya da Silinecek Kayit Ismi : ");

fflush(stdin); gets(aranan_isim);

gecici = ilk;

while(strcmp(gecici->isim,aranan_isim)){//esit olmadıgı surece döner. bkz.(strcmp();)
gecici = gecici->sonraki;
}

printf("Kayit Bulundu : %s",gecici->isim);
}

Aradık ve bulduk diyelim.Silmek istiyorsak; Sil fonksiyonunun ilk önce Ara fonksiyonu ile iletişime geçip silinecek ismi belirlemesi lazım.Ardından silmenin ilk, son veya aradan bir kayıtla mı alakalı olduğu belirlenip ona göre işlem yapılmalıdır.

void Sil(){

Ara();

if(gecici->sonraki == NULL){//silinmek istenen son kayit ise;

son = son->onceki;
son->sonraki = NULL;
free(gecici);
}

else if(gecici->onceki == NULL){//ilk kayit silinecekse;

ilk = ilk->sonraki;
ilk->onceki = NULL;
free(gecici);
}

else{//aradan bir kayit siliniyor ise;

struct Kayit *temp1, *temp2;

temp1 = gecici;//silinen adresi free lemek için lazım.
temp2 = temp1->onceki;//silinecek kaydın öncesini tutalım.
temp1 = temp1->sonraki;//bir de sonrakini tutalım.

//temp1' de silinecek kayittan sonraki, temp2'de silinecek kayittan önceki var.
temp2->sonraki = temp1;//şimdi tutulanları bağlayalım.
temp1->onceki = temp2;

free(gecici);//koparılan bağı da silmek lazım.
}
}

Guncellemek silmekten çok daha basit aslında.Çünkü silerken aradan bir bağ kopuyor ve kopan bağın öncekisini ve sonrakisini birbirine bağlamak gerekiyor.

void Guncelle(void){

Ara();

//Guncellenecek kaydın adresine ulaştıktan sonra;

printf("\nGuncel Kayit Ismi : ");

fflush(stdin); gets(gecici->isim);

}

En basit hali ile fonksiyonlar bu şekilde.Zaten bunu anladıktan sonra daha karmaşıklarını yapmak çok zor olmayacak.

İyi çalışmalar.

  • malik

    2şey söyleyeceğim 1.cisi niye kodlar 2kez verilmiş
    2.si çok şey mi istiyorum bilmiyorum ama tüm kod olsa daha iyi olmaz mıydı :D:D

    • Turgay Özgür

      Kodlar 2 kez verilmiş derken ne demek istediğini anlamadım.
      Ayrıca kodları birleştirdiğinde çalışan tek bir program elde edebilirsin.

  • muhendis adayi

    baglı liste içerisinde arama yaparken int i = 0; tanımlaması gereksiz tanımlanmış ama kullanılmamış

    • Turgay Özgür

      Düzeltmeniz için teşekkür ediyorum.Gözden kaçmış olsa gerek.Şimdi düzeltildi.

  • selam

    listenin herbir dugumunde adi,soyadi,numara gibi verileri nasıl tutabiliriz.

    • http://turgayozgur.com/ Turgay Özgür

      Listenin en başında tanımladığım struct’ı şöyle genişleterek yapabilirsiniz:

      struct Kayit{
      char ad[20];
      char soyad[20];
      char numara[10];
      Kayit *sonraki, *onceki;
      };

      Buradaki 20-20-10 değerlerini istediğiniz gibi artırıp azaltabilirsiniz.

      • selam

        teşekkurler peki listenin basına ve ortasına nasıl kayit ekleyebiliriz?

        • http://turgayozgur.com/ Turgay Özgür

          Ekle metodunda bağların nasıl kurulduğunu inceleyiniz. Benzer şekilde siz de son elemana değil ilk elemana bu bağı kuracak şekilde kod yazmak için çalışın. Olayın mantığını kavradıktan sonra rahatlıkla yapabilirsiniz.

          • selam

            B+ agacında ekleme,silme,arama ile ilgili paylasımınız varmı kodlaması nasıl oluyor

  • yusuf kara

    hocam kodları çalıştıramadım, c de yeniyim ve öğrenmek istiyorum, mantıken anladım gibi ama yinede kodları toparlayıp çalıştıramadım :( yardımcı olur musunuz lütfen c dosyası varsa yükleyebilir misiniz?

  • Merhaba

    Peki listenin her bir düğümünde verileri sıra sıra nasıl ekleyebiliriz.Yani demek istediğim 1. düğüm için bilgileri girdikten sonra 2. düğüm için aynı bilgiler nasıl eklenir teşekkürler…

    • Merhaba

      Eklemeyi hallettim fakat her bir düğümün bilgilerini yazdırmada sorun var.Nasıl yazdırabilirim ?

      • http://turgayozgur.com/ Turgay Özgür

        Yukarıdaki listele fonksiyonunu kullanabilirsiniz. Eğer kullandiysaniz nasil bir sorunla karşılaştınız?

        • merhaba

          struct isimKayit{

          char guzergah[20],plaka[10],kaptan[30],tarih[20],saat[10];

          char kapasite[10],fiyat[5];

          isimKayit *k_ptr;

          };

          isimKayit *ilk, *son, *onceki, *sonraki, *gecici;

          otobüs otomasyonu için bağlı liste yapıyorum.Sefer 1 ,sefer 2,sefer 3.. gibi her sefer için bilgileri yazdırmamız gerekiyor fakat sadece guzergah bilgilerini yazdırabiliyorum.

          gecici = ilk;

          while(gecici != NULL){

          printf(“nt%sn”,gecici);

          gecici = gecici->k_ptr;

          } printf(“t——-“);

          Yazdırma için kullandığım fonksiyon bu .Dİğer bilgileri de yazdırmamız içi ne lazım tam olarak ?

          • http://turgayozgur.com/ Turgay Özgür

            printf(“nt%sn”,gecici);

            satırındaki gecici yerine gecici->guzergah yazarak güzergahı ekrana basabilirsiniz. Benzer şekilde diğer bilgileri de yazdırabilirsiniz. Örneğin iki bilgi için:

            printf(“Plaka:%s, Kaptan:%sn”, gecici->plaka, gecici->kaptan);

  • merhaba

    çift yönlü bagıl listeyi dosyayı yazdırmayı nasıl yapabiliriz

    fprintf(dosya_kayit, “%st%st%st%st%st%st%st%st%sn”,Kayit.nereden,Kayit.nereye,Kayit.adi,Kayit.soyadi,Kayit.TC,Kayit.ytelnum,Kayit.adres,Kayit.koltuk,Kayit.sefer );

    • http://turgayozgur.com/ Turgay Özgür

      listele fonksiyonu içerisinde döngüyü şu şekilde kurabilirsiniz.

      while(!feof(dosya_kaydet))
      {
      if (gecici == null) break;

      }

  • mustafa

    ya lutfen yardımcı olun vizelerim baslıcak ve bu konu hakkında hiç bi fikre sahip degilim -> isareti tam olarak ne anlama gelior bu baglı liste yapmaktaki amac ne .hangi durumlarda bunlardan yararlanmamaız gerekiyor,structlardaki tanımladıgımız ;
    *ilk,*son,*sonraki*önceki kelimenin tam anlamıyla ne acıklarmısınız kafamda bi cok soru işareti kaldı
    belki farkında olmadan sacma sorular sordum ama konuya gercekten cok uzagım ama lutfen yardımcı olmaya calısın…simdiden tesekkurler ..iyi calısmalar…

  • user

    çok teşekkür ederim projemi yapmakta çok yararlı oldu.

  • Engin Toplu

    çok teşekkürler

Yeni makaleleri E-Mail ile takip edin!