Ödev 3: Bağlaçlı Listeler

14 Nisan 2008 tarihinde aldığımız Bağlaçlı Listeler ödevi için teslim ettiğim kaynak kod. Ödevinden isminden de anlaşılabileceği gibi ödevin asıl amacı C# dilinde bağlaçlı liste yönetmeyi başarabilmek. Bu ödevimde (en azından ben hata göremedim ödevi gönderdiğimde) bağlaçlı liste kullanımına örnek bulabileceksiniz.

Kaynak kodunu incelemek ve fikir sahibi olmak amacıyla kullanabilirsiniz. Ama lütfen kaynak kodunu kopyala yapıştır yapmayalım, kendimize mal etmeyelim. Onun yerine nasıl çalıştığını inceleyip kavrama yoluna gidelim.

Sınav dönemine geldik. Haydi hayırlısı.

Ek: Bu ödev 100 aldı.

Kaynak kodunu indirmek istemezseniz aşağıda da aynısını bulabilirsiniz.

 #include <stdio.h> #include <stdlib.h>

#define NO 1 #define AD 2 #define STOK_LIMIT_YOK -1

/* Sabitler ve Anlamlari */ /* --------------------- */ /* NO : urun_baglanacak fonksiyonun neye göre geriye veri göndereceğini belirten sa- bitlerden bir tanesi. AD ile aynı olmamak koşuluyla her şey olabilir. AD : urun_baglanacak fonksiyonun neye göre geriye veri göndereceğini belirten sa- bitlerden bir tanesi. NO ile aynı olmamak koşuluyla her şey olabilir. STOK_LIMIT_YOK : İlgili fonksiyonun parametresindeki stok limiti kısmını göz ardı etmesini sağlayan sabit. Negatif herhangi bir sayı ile değiştirilebilir. */

/* Yapılar */ struct URUN_YAPI { int urun_kodu; char urun_adi[20]; float birim_alis_fiyati; int stok_miktari; struct URUN_YAPI *sonraki; struct URUN_YAPI *sonraki_ad; struct SATIS_YAPI *link; };

struct SATIS_YAPI { char fatura_no[6]; char satis_tarihi[6]; int satis_miktari; float birim_satis_fiyati; struct SATIS_YAPI *sonraki; };

/* Kullanıcı tanımlı tipler */ typedef struct URUN_YAPI URUN; typedef struct SATIS_YAPI SATIS;

void beklet() { /* Bu fonksiyonun tek amaci kullaniciyi bir tusa basana kadar bekletmek, ve sonra ekrani silmektir. */ printf("\nDevam etmek icin bir tusa basin."); getche(); system ("cls"); }

void urun_baglanacak(URUN *liste_basi, int urun_kodu, char urun_adi[20], int ne, URUN **gonderilecek) {

/* Ne parametresinde aldığı bilgiye göre urun_kodu ya da urun_adi'ne göre guncel listede arama yapar ve ürün kodu/adı'ndan bir küçük koda/ada sahip ürünün bellekteki adresini gönderir. (yoksa listebaşı) */

URUN *guncel;

if (ne == NO) { /* Ürün koduna göre sıralayacak ve bir adres göndereceğiz. */

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ *gonderilecek = liste_basi;

/* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) { /* Baştan başla geriye dönene kadar uç */

if (guncel->urun_kodu >= urun_kodu) { return 0; }

*gonderilecek = guncel; /* Bir öncekini göndereceğimiz için bir yerde tutmak lazım geliyor. */ guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */

}

return 0; /* Eğer buraya geldiyse eşleşme yok demektir. */

} else { /* İsme göre sıralayacak ve bir adres göndereceğiz. */

guncel = liste_basi->sonraki_ad; /* Güncel en başta 1.kayıt olsun */ *gonderilecek = liste_basi;

/* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) { /* Baştan başla geriye dönene kadar uç */

if (strncmp(guncel->urun_adi,urun_adi,20) >=0) { return 0; }

*gonderilecek = guncel; /* Bir öncekini göndereceğimiz için bir yerde tutmak lazım geliyor. */ guncel = guncel->sonraki_ad; /* Bir sonraki kayıda uçalım. */

}

return 0; /* Eğer buraya geldiyse eşleşme yok demektir. */

}

}

void urun_ekle(URUN *liste_basi, int urun_kodu, char urun_adi[20], float birim_alis_fiyati, int stok_miktari) {

URUN *adres; int sayac; URUN *onceki_urun;

adres=malloc(sizeof(URUN)); /* Azıcık bellek tahsis edelim kendimize. */

/* İçine gerekli verileri yazalım. */ adres->urun_kodu = urun_kodu; for (sayac=0;sayac<20;sayac++) { adres->urun_adi[sayac] = urun_adi[sayac]; } adres->birim_alis_fiyati = birim_alis_fiyati; adres->stok_miktari = stok_miktari; adres->link = NULL; /* Yazdık. */

/* Şimdi öncesini sonrasını ayarlayalım ki dairesel bir bağlaç oluşsun. */

/* Numaraya göre */ urun_baglanacak(liste_basi,urun_kodu,urun_adi,NO,&onceki_urun);

adres->sonraki = onceki_urun->sonraki; onceki_urun->sonraki = adres; /* Ada göre */

urun_baglanacak(liste_basi,urun_kodu,urun_adi,AD,&onceki_urun);

adres->sonraki_ad = onceki_urun->sonraki_ad; onceki_urun->sonraki_ad = adres;

/* Burada da bağlantılar ayarlanacak ama şimdi diil */

}

int urun_var_mi(URUN *liste_basi, int urun_kodu) {

/* 1: Ürün var 0: Ürün yok */

URUN *guncel;

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi || guncel->urun_kodu > urun_kodu) { /* Baştan başla geriye dönene kadar uç */

if (guncel->urun_kodu == urun_kodu) { return 1; }

guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */

}

return 0; /* Eğer buraya geldiyse eşleşme yok demektir. */

}

void urun_duzenle(URUN *liste_basi, int urun_kodu, float birim_alis_fiyati, int stok_miktari) {

URUN *guncel;

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) { /* Baştan başla geriye dönene kadar uç */

if (guncel->urun_kodu == urun_kodu) {

guncel->birim_alis_fiyati = birim_alis_fiyati; guncel->stok_miktari = stok_miktari; return 0; }

guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */ } }

void urun_listele(URUN *liste_basi, int stok_miktari,int ne) {

URUN *guncel;

printf("Urun Kodu Urun Adi Stok Miktari Bilim Alis Fiyati\n"); printf("--------- -------------------- ------------ -----------------\n");

if (ne == NO) { /* Liste numaraya göre sıralı gösterilecek */

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) { /* Baştan başla geriye dönene kadar uç */

if (stok_miktari == STOK_LIMIT_YOK || guncel->stok_miktari <= stok_miktari) { printf("%9d %20s %12d %17.2f %p %p %p\n",guncel->urun_kodu,guncel->urun_adi,guncel->stok_miktari,guncel->birim_alis_fiyati, guncel, guncel->sonraki, guncel->sonraki_ad); } guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */ }

} else { /* Liste ada göre sıralı gösterilecek. */

guncel = liste_basi->sonraki_ad; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) { /* Baştan başla geriye dönene kadar uç */

if (stok_miktari == STOK_LIMIT_YOK || guncel->stok_miktari <= stok_miktari) { printf("%9d %20s %12d %17.2f\n",guncel->urun_kodu,guncel->urun_adi,guncel->stok_miktari,guncel->birim_alis_fiyati); } guncel = guncel->sonraki_ad; /* Bir sonraki kayıda uçalım. */ }

} }

void urun_sil(URUN *liste_basi, int urun_kodu) {

URUN *guncel; URUN *onceki_urun; SATIS *sil_konum;

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) { /* Baştan başla silenecek öğeyi bulana kadar uç */

if (guncel->urun_kodu == urun_kodu) { /* İşe silinecek öğe! Sileceğim seni nhahahaha! */

/* Ürüne bağlı satışları silelim */

sil_konum = guncel->link; while(sil_konum!=NULL) { sil_konum = sil_konum->sonraki; free(sil_konum); }

/* Silmeden önce önceki kaydın bağını sonrakine almalıyız.*/

/* Numaraya göre bir önceki ürünü bul*/ urun_baglanacak(liste_basi,urun_kodu,guncel->urun_adi,NO,&onceki_urun); onceki_urun->sonraki = guncel->sonraki;

/* Ada göre bir önceki ürünü bul */ urun_baglanacak(liste_basi,urun_kodu,guncel->urun_adi,AD,&onceki_urun); onceki_urun->sonraki_ad = guncel->sonraki_ad;

/* Sil gitsin */ free(guncel);

return 0; }

guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */

}

}

void satis_ekle(URUN *liste_basi, int urun_kodu, char fatura_no[6], char satis_tarihi[6], int satis_miktari, float birim_satis_fiyati) {

URUN *guncel; SATIS *gezinti; SATIS *adres; SATIS *onceki; int sayac; adres=malloc(sizeof(SATIS)); /* Azıcık bellek tahsis edelim kendimize. */

/* İçine gerekli verileri yazalım. */ for (sayac=0;sayac<6;sayac++) { adres->fatura_no[sayac] = fatura_no[sayac]; }

for (sayac=0;sayac<6;sayac++) { adres->satis_tarihi[sayac] = satis_tarihi[sayac]; } adres->satis_miktari = satis_miktari; adres->birim_satis_fiyati = birim_satis_fiyati; /* Yazdık. */

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi || guncel->urun_kodu > urun_kodu) {

if (guncel->urun_kodu == urun_kodu) { /* Ürünü bulduk, hadi neymiş inceleyelim. */

/* Durum 1: Daha önce satış eklenmemiş olabilir. */

if (guncel->link == NULL) { /* daha önce ürün eklemesi yapılmamış. hemen ekliyoruz. */ adres->sonraki = NULL; guncel->link = adres; } else {

/* Durum 2: Yeni eklenen satış şimdiye kadarkilerin en büyüğü olabilir ki ürünler kısmında değişiklik gerekir. */ if(strncmp(satis_tarihi,(guncel->link)->satis_tarihi,6)>0) { /* Bu satirda hata yoksa hiçbir satırda yoktur artık :) */ adres->sonraki = guncel->link; guncel->link = adres; } else { /* Durum 3: Yeni eklenen herhangi bir arada ya da en sonra olabilir. */ gezinti = guncel->link; /* Gezintiye ilk kaydın adresini ata */

do { /* Son kayda kadar */

if(strncmp(satis_tarihi,gezinti->satis_tarihi,6) > 0) {

adres->sonraki = gezinti; onceki->sonraki = adres; return 0; }

onceki = gezinti; gezinti = gezinti->sonraki;

} while (gezinti != NULL);

adres->sonraki = gezinti; onceki->sonraki = adres; } } } guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */ } }

void satis_listele(URUN *liste_basi, int urun_kodu) {

URUN *guncel; SATIS *gezinti;

printf("%d numarali urunun satis listesi\n",urun_kodu); printf("\n"); printf("FATURA NO SATIS TARIHI SATIS MIKTARI BIRIM SATIS FIYATI\n"); printf("--------- ------------ ------------- ------------------\n");

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) {

if (guncel->urun_kodu == urun_kodu) { /* Ürünü bulduk, hadi ekrana satışları yazalım. */

if (guncel->link == NULL) { /* heheee çökertemezsiniz */

printf("(satis kaydi yok)\n"); return 0;

} else {

gezinti = guncel->link; while (gezinti != NULL) { printf(" %c%c%c%c%c%c %c%c%c%c%c%c %13d %18.4f \n",gezinti->fatura_no[0],gezinti->fatura_no[1],gezinti->fatura_no[2],gezinti->fatura_no[3],gezinti->fatura_no[4],gezinti->fatura_no[5],gezinti->satis_tarihi[0],gezinti->satis_tarihi[1],gezinti->satis_tarihi[2],gezinti->satis_tarihi[3],gezinti->satis_tarihi[4],gezinti->satis_tarihi[5],gezinti->satis_miktari,gezinti->birim_satis_fiyati); gezinti = gezinti->sonraki; } } return 0; } guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */ }

}

void tum_urun_top_satis(URUN *liste_basi) {

URUN *guncel; SATIS *gezinti;

int satis_urun; int satis_top=0; float ciro_urun; float ciro_top=0L;

printf("Urun Kodu Urun Adi Toplam Satis Miktari Toplam Ciro\n"); printf("--------- -------------------- -------------------- -----------\n");

guncel = liste_basi->sonraki; /* Güncel en başta 1.kayıt olsun */ /* Dikkat: Yukarıdaki satıra dikkat edilirse, eğer liste boşsa while döngüsüne girilmeyecektir. */

while(guncel != liste_basi) { /* Baştan başla geriye dönene kadar uç */

/* Satışlarla ilgili gerekli hesaplamaları yapalım */ satis_urun = 0; ciro_urun = 0L; if (guncel->link != NULL) { /* heheee çökertemezsiniz */ gezinti = guncel->link; while (gezinti != NULL) { satis_urun += gezinti->satis_miktari; ciro_urun += gezinti->satis_miktari * gezinti->birim_satis_fiyati;

gezinti = gezinti->sonraki; } }

printf("%9d %20s %20d %11.4f\n",guncel->urun_kodu,guncel->urun_adi,satis_urun,ciro_urun);

ciro_top += ciro_urun; satis_top += satis_urun;

guncel = guncel->sonraki; /* Bir sonraki kayıda uçalım. */ }

printf("---------------------------------------------------------------\n"); printf("Toplam: %22d %11.4f\n",satis_top,ciro_top);

}

int main() {

/* Acilis yazilari BASLANGICI */ printf("Umut BENZER\n"); printf("05-06-7670\n"); printf("Ege Universitesi Bilgisayar Muhendisligi 1\. Sinif\n"); printf("http://www.ubenzer.com\n"); printf("Odev 3\n\n"); /* Acilis yazilari SONU */

/* Verilerin tutalacağı YAPILAR */

URUN liste_basi;

/* Verilerin tutulacağı YAPILAR SONU */

int sag_serbest=-1; int sayac; int girdi; char girdi2[20]; float girdi3; int girdi4; char girdi5[6]; char girdi6[6]; char secenek; /* Girdi degiskenleri main fonksiyonun her bir yerinde farkli farkli bir sürü amaçla kullanıldığı için özel isimler vermedim. */

liste_basi.urun_kodu = -1; for (sayac=0;sayac<20;sayac++) { liste_basi.urun_adi[sayac] = '_'; } liste_basi.birim_alis_fiyati = 0.0; liste_basi.stok_miktari = 0; liste_basi.sonraki = &liste_basi; liste_basi.sonraki_ad = &liste_basi; liste_basi.link = NULL;

/* Ana döngü */ while (sag_serbest==-1) {

/* menu BASLANGICI */ printf("*** Menu *** \n\n"); printf("1\. Yeni bir urunun eklenmesi \n"); printf("2\. Bir urunun birim alis fiyatinin ve stok miktarinin guncellenmesi \n"); printf("3\. Bir urune iliskin satis eklenmesi \n"); printf("4\. Bir urunun silinmesi \n"); printf("5\. Bir urunden yapilan tum satislarin listelenmesi \n"); printf("6\. Tum urunlerin koda gore sirali olarak listelenmesi \n"); printf("7\. Tum urunlerin ada gore sirali olarak listelenmesi \n"); printf("8\. Belirli bir stok miktarinin altinda urunlerin listelenmesi \n"); printf("9\. Tum urunlerden yapilan toplam satislarin listelenmesi \n"); printf("C. Cikis \n");

printf("Lutfen istediginiz islemin numarasini giriniz.\n"); /*menu BITIMI */

secenek=getche(); system ("cls");

/* secenek getche ile alındığı için ASCII koduna göre switch yapısına sokulabilir. */

/* Her CASE için aşağıdaki not geçerlidir. */

/* Gerekli saçma sapan veri kontrolleri ve doğru girdi için ilgili fonksiyonların çağırılması, fonksiyon- lardan cevap alınması ve bunların işlenmesi.

Ayrıntılı bilgi için her fonksiyona ayrı ayrı baka- bilirsiniz. */

switch(secenek) { case 49: //1

system ("cls"); printf("Yeni bir urun kodu giriniz: \n"); scanf("%d",&girdi); system ("cls");

switch (urun_var_mi(&liste_basi,girdi)) {

case 0: /* Yaşasın doğru girmişler. */

for (sayac=0;sayac<20;sayac++) { girdi2[sayac] = NULL; }

while (girdi2[0] == NULL) { fflush(stdin); printf("Yeni urunun adini giriniz: "); gets(girdi2); }

printf("Urunun alis fiyatini giriniz: "); scanf("%f",&girdi3);

printf("Urunun stok durumunu giriniz: "); scanf("%d",&girdi4);

urun_ekle(&liste_basi, girdi, girdi2, girdi3, girdi4); printf("Islem tamam. ;)\n"); break;

case 1: printf("Girdiginiz urun kodu daha once alinmis.\n"); break; } beklet(); break; case 50: //2 system ("cls"); printf("Duzenlenecek urun kodunu giriniz: \n"); scanf("%d",&girdi); system ("cls");

switch (urun_var_mi(&liste_basi,girdi)) {

case 1: /* Yaşasın doğru girmişler. */

printf("Urunun yeni alis fiyatini giriniz: "); scanf("%f",&girdi3);

printf("Urunun yeni stok durumunu giriniz: "); scanf("%d",&girdi4);

urun_duzenle(&liste_basi, girdi, girdi3, girdi4); printf("Islem tamam. ;)\n"); break;

case 0: printf("Boyle bir urun yok. Bohuuu...\n"); break; } beklet(); break; case 51: //3

system ("cls"); printf("Satis eklenecek urun kodunu giriniz: \n"); scanf("%d",&girdi); system ("cls");

switch (urun_var_mi(&liste_basi,girdi)) {

case 1: /* Evet var. */

for (sayac=0;sayac<6;sayac++) { girdi5[sayac] = NULL; }

while (girdi5[0] == NULL) { fflush(stdin); printf("Fatura kodunu giriniz (6 karakter): "); gets(girdi5); }

for (sayac=0;sayac<6;sayac++) { girdi6[sayac] = NULL; }

while (girdi6[0] == NULL) { fflush(stdin); /* Ödevin asıl amacının tarihlerle değil de bellekle uğraşmak olduğu bilindiğinden 2000 öncesi yıllar için sıralama sorunu ihmal edildi. */ printf("Satis tarihini giriniz (YYAAGG): "); gets(girdi6); }

printf("Urunun satis miktarini giriniz: "); scanf("%d",&girdi4);

printf("Birim satis fiyatini giriniz: "); scanf("%f",&girdi3);

satis_ekle(&liste_basi, girdi, girdi5, girdi6, girdi4, girdi3); printf("Islem tamam."); break;

case 0: /* Hayır, yok */ printf("Boyle bir urun yok."); break; } beklet(); break; case 52: //4

system ("cls"); printf("Silinecek urun kodunu giriniz: \n"); scanf("%d",&girdi); system ("cls");

switch (urun_var_mi(&liste_basi,girdi)) {

case 1: /* Yaşasın doğru girmişler. */ urun_sil(&liste_basi, girdi); printf("Sildim bile."); break; case 0: printf("Boyle bir urun zaten yok ki. :)\n"); break; }

beklet(); break; case 53: //5 system ("cls"); printf("Satislari listelenecek urun kodunu giriniz: \n"); scanf("%d",&girdi); system ("cls");

switch (urun_var_mi(&liste_basi,girdi)) {

case 1: /* Yaşasın doğru girmişler. */

satis_listele(&liste_basi, girdi); break;

case 0: printf("Boyle bir urun yok. Bohuuu...\n"); break; } beklet(); break; case 54: //6 urun_listele(&liste_basi, STOK_LIMIT_YOK, NO); beklet(); break; case 55: //7 urun_listele(&liste_basi, STOK_LIMIT_YOK, AD); beklet(); break;

case 56: //8 girdi = STOK_LIMIT_YOK; while(girdi == STOK_LIMIT_YOK) { system("cls"); printf("Kactan kucuk olsun istiyorsunuz? "); scanf("%d",&girdi); }

/* Dikkat: Ödevde istenmeyen ek özelliktir. */

system("cls"); printf("Neye gore sirali istersiniz? (%d urun koduna gore, %d ada gore)",NO,AD); scanf("%d",&girdi4);

urun_listele(&liste_basi, girdi, girdi4); beklet(); break;

case 57: //9

tum_urun_top_satis(&liste_basi); beklet(); break; case 99: //c case 67: //C /* E e H h ve disinda girdi kabul etmeyen cikmak istiyor musunuz sorusu BASLANGICI */ do { printf ("\nCidden cikmak istiyor musunuz? (E/H) "); secenek = getche(); if (secenek == 'E' || secenek == 'e') { sag_serbest = 0; secenek = 'H'; } } while (secenek != 'H' && secenek != 'h'); /* E e H h ve disinda girdi kabul etmeyen cikmak istiyor musunuz sorusu SONU */ system ("cls"); break; case 65: printf("There are no choices. Nothing but a straight line. The illusion\n"); printf("comes afterwards, when you ask 'Why me?' and 'What if?'. When you\n"); printf("look back and see the branches, like a pruned bonsai tree, or\n"); printf("forked lightning. If you had done something differently, it\n"); printf("wouldn't be you. It would be someone else looking back, asking a\n"); printf("different set of questions. (a quote from Max Payne)\n"); printf("\n\n"); printf("Press any key to continue..."); getche(); system("cls"); printf("Supriz Yumurta | Easter Egg\n"); printf("Tebrikler, bu programin gizli ozelligini buldunuz. :)\n"); printf("\n"); printf("http://www.imdb.com/title/tt0366758/quotes\n"); beklet(); break; default: /* Elleri yanlis tusa basan kullanicilar icin yazilan bolum BASLANGICI */ printf("Bir zahmet 1'den 9'a kadar bir secim yapin."); beklet(); /* Elleri yanlis tusa basan kullanicilar icin yazilan bolum SONU */ break; } }

printf("O halde hoscakalin. :)\n\n\n"); return 0; }