PDA

Tam Sürümünü Görmek İçin : Menü kullanımlı Circular Double Linked List uygulaması


RaiST
13/11/2002, 12:18
Evet ödev olarak hazırladğım bir örnek daha:

Ekran çıktısı:


Veri Yapıları Ödevi 1 - Hüseyin Uslu
.:: ------------------------------------ ::.
Menüde gezinmek için aşağı, yukarı ok tuşlarını, seçim için Enter'ı kullanınız
Programdan çıkmak için ESC'e basınız

+----------------------------------+
¦ Liste Yarat ¦
¦ Listeyi Yazdır ¦
¦__________Listeyi Sırala__¦
¦ Yeni Node Ekle ¦
¦ Node Sil ¦
¦ Member() ¦
¦ Locate() ¦
¦ Count() ¦
¦ Listeleri Birleştir ¦
¦ ¦
¦ ¦
+----------------------------------+
liste: c->e->v->i->z->.->n->e->t


işte kod

umarım işe yarar:
---------------------------------------------------------------------------------



#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <alloc.h>
#include <dos.h>

/* Linked listimiz in node tanımlaması.*/
/* Node'un türkçe karşılığı tam olmasada Nesne olarak kullandım*/

struct nesne
{
char karakter;
struct nesne * ileri;
struct nesne * geri;
};

typedef struct nesne NESNE;

/* linked list işlemi yapan fonskiyonlar */

NESNE * CreateList();
void printList(NESNE *);
void Sort(NESNE *);
NESNE * Insert(NESNE *);
NESNE * Delete(NESNE *);
int Member(NESNE * , char);
int Count(NESNE *);
NESNE * Locate(NESNE *,char);
NESNE * Concatenate(NESNE *, NESNE *);

/* menu fonksiyonlari */

void PrintMenuSelection(int);
void ClearMenuSelections();
void PrintMenu();
void PrintMenuText();

/* Main fonksiyonu */
/* Menü işlemleri ve key okuma işlemleri burada yapılmaktadır. */
void main()
{

NESNE * liste=NULL,* liste2=NULL,* LocateNesne=NULL;

int key;
int selection=1;
char arancak;

PrintMenu();
PrintMenuText();
PrintMenuSelection(selection);

while(1)
{
if (kbhit())
{

PrintMenu();
PrintMenuText();

printList(liste);

key=getkey();

if (key==27)
{
return 0;
}
else if (key==336)
{
selection++;
if (selection==10)
selection=1;

ClearMenuSelections();
PrintMenuSelection(selection);
}

else if (key==328)
{
if (selection==1)
selection=10;

selection--;
ClearMenuSelections();
PrintMenuSelection(selection);
}

else if (key==13)
{
/*secim*/

clrscr();
if (selection==1)
{
liste=CreateList();
}
else if(selection==2)
{
printList(liste);
}
else if(selection==3)
{
Sort(liste);
}
else if(selection==4)
{
liste=Insert(liste);
}
else if(selection==5)
{
liste=Delete(liste);
}
else if(selection==6)
{
printf("Aranacak karakteri giriniz:");
flushall();
arancak=getch();
printf("%c",arancak);

if (Member(liste,arancak)==1)
{
printf("\n%c karakteri dizinin uyesidir",arancak);
}
else
{
printf("\n%c karakteri dizinin uyesi de§ildir",arancak);

}

getch();
}
else if(selection==7)
{
printf("Yeri bulunacak karakteri giriniz:");
flushall();
arancak=getch();
printf("%c",arancak);
LocateNesne=Locate(liste,arancak);
if (LocateNesne!=NULL)
{
printf("\nkarakterin listedeki yeri bulundu\n");
printf("geri d”nen NESNE'nin NESNE->karakter işleminin sonucu=%c\n",LocateNesne->karakter);
printf("Geri d”nen nesne'nin adresi: %x",LocateNesne);
}
else
{
printf("\nkarakter listede bulunamad!");
}
getch();
}
else if(selection==8)
{
printf("Listedeki toplam eleman sayısı=%d",Count(liste));
getch();
}
else if(selection==9)
{
liste2=CreateList();
liste=Concatenate(liste,liste2);

}

PrintMenu();
PrintMenuText();
printList(liste);
PrintMenuSelection(selection);

}
}
}
}


NESNE * CreateList()
{
/ * liste yarattığımız fonksiyon.
Fonksiyon içinde kullanıcıdan data girilmesi istenir ve data girilmeye devam edip edilmeyeceği sorulur.
Işlem bittikten sonra NESNE * türünde geri gönderiyoruz */

NESNE *gecici,*sol,*sag,*liste;
int devam;
char devam_chr;

devam=1;

gecici=(NESNE *)malloc(sizeof(NESNE));

liste=gecici; /* listeye liste başını aktarıyoruz. return ederken liste başını göndermeliyiz*/

while(devam==1)
{
clrscr();
printf("\nNode'un tutaca§ karakteri giriniz:");
gecici->karakter=getch();
printf("%c\n",gecici->karakter);
flushall();
printf("Eklemeye devam etmek i‡in E'ye basnz. Di§er tuŸlara basarak node eklemeyi durdurabilirsiniz.");
devam_chr=getch();

if (devam_chr=='E' | devam_chr=='e' )
{
devam=1;
gecici->ileri=(NESNE*)malloc(sizeof(NESNE));

sol=gecici;
gecici=gecici->ileri;
gecici->geri=sol;

}
else
{
devam=0;
gecici->ileri=liste;
liste->geri=gecici;
}


}

return liste;

}

void printList(NESNE * liste)
{
/* verilen NESNE * türündeki argümanın datalarını ekrana yazdırır */

NESNE * gecici;

if (liste!=NULL)
{
printf("\n");
gecici=liste;

gotoxy(1,22);
printf("liste: ");

while (gecici->ileri!=liste & gecici->ileri!=gecici)
{
printf("%c->",gecici->karakter);
gecici=gecici->ileri;
}

printf("%c\n",gecici->karakter);


}
}

int Count(NESNE * liste)
{

/* verilen listenin elaman sayınısı sayıp int olarak geri döndürür */
NESNE * gecici;
int i;

i=0;

gecici=liste;

while(gecici->ileri!=liste)
{
i++;
gecici=gecici->ileri;

}

if(i!=0)
{
i++;
}

return i;


}


void Sort(NESNE * liste)
{
/* verilen listenin elamanlarını ascii karşılıklaırna göre küçükten büyüğe veya büyükten küçüğe doğru
sıralar */
NESNE * gecici;
int toplam;
int i,j;
char yedek;
char secim;

gecici=liste;
toplam=Count(liste);
printf("toplam=%d",toplam);

printf("\n Listenin bykten k‡§e sralanmas i‡in 1'e, k‡kten by§e sralanmas i‡in 2 ye basnz");
secim=getch();
printf("secim %c",secim);

if (secim=='1')
{

for(i=0;i<toplam;i++)
{


for(j=0;j<toplam-1;j++)
{
if (gecici->karakter > gecici->ileri->karakter )
{
yedek=gecici->karakter;
gecici->karakter=gecici->ileri->karakter;
gecici->ileri->karakter=yedek;
}
gecici=gecici->ileri;
}
gecici=gecici->ileri;
}

}

else if (secim=='2')
{

for(i=0;i<toplam;i++)
{

for(j=0;j<toplam-1;j++)
{
if (gecici->karakter < gecici->ileri->karakter )
{
yedek=gecici->karakter;
gecici->karakter=gecici->ileri->karakter;
gecici->ileri->karakter=yedek;
}
gecici=gecici->ileri;
}

gecici=gecici->ileri;
}


}

else
{
printf("anlayamadım!");
}

}

NESNE * Insert (NESNE * liste)
{

/*listeye verilen bir pozisyonda yeni bir node ekler*/
NESNE * new;
NESNE * gecici;
NESNE * onceki;
char new_chr;
int position;
int i;

gecici=liste;

new=(NESNE *)malloc(sizeof(NESNE));
printf("eklenecek yeni node i‡in karakter giriniz:");
new->karakter=getch();
printf("%c",new->karakter);
printf("\neklenecek yeni nodeun posizyonunu giriniz:");
scanf("%d",&position);

if (position==0)
{
/*liste sonuna git */
while(gecici->ileri!=liste)
{
gecici=gecici->ileri;
}

gecici->ileri=new;
new->ileri=liste;
liste->geri=new;
new->geri=gecici;

liste=new;
}

else
{
for(i=0;i<position;i++)
{

onceki=gecici;
gecici=gecici->ileri;
}


new->ileri=gecici;
onceki->ileri=new;
new->geri=onceki;
gecici->geri=onceki;


}


return liste;
}


NESNE * Delete(NESNE * liste)
{


/* seçilen pozisyondaki nodeu siler*/
int pozisyon;
NESNE * current;
NESNE * gecici;
NESNE * onceki;
int i;
int j=0;

gecici=liste;

printf("silinecek nodeun posizyonunu giriniz:");
scanf("%d",&pozisyon);


if (pozisyon==0)
{

current=liste;

while (gecici->ileri!=liste)
{
j++;
gecici=gecici->ileri;
}

if (j!=0)
{
gecici->ileri=current->ileri;
current->ileri->geri=gecici;
liste=current->ileri;
free(current);
}
else
{
/*listede sadece 1 tane node var. bunu dorudan freele ve hi‡bir node kalmad§
i‡in geriye NULL g”nder */

free(current);
return NULL;
}
}
else
{

for(i=0;i<pozisyon;i++)
{

onceki=gecici;
gecici=gecici->ileri;

}

onceki->ileri=gecici->ileri;
gecici->ileri->geri=onceki;

free(gecici);


}

return liste;

}

int Member(NESNE * liste,char deger)
{
/*listede verilen karakterin tutulup tutulmadığını bulur*/
NESNE * gecici;
gecici=liste;
while(gecici->ileri!=liste)
{

if (gecici->karakter==deger)
{
return 1;
}

gecici=gecici->ileri;
}

if (gecici->karakter==deger)
{
return 1;
}


return 0;
}

NESNE * Locate(NESNE * liste,char deger)
{
/*verilen değerin listedeki nodeunu geri döndürür*/
NESNE * gecici;
gecici=liste;

while(gecici->ileri!=liste)
{
if (gecici->karakter==deger)
{
return gecici;
}

gecici=gecici->ileri;

}

if (gecici->karakter==deger)
{
return gecici;
}

return NULL;
}


NESNE * Concatenate(NESNE * liste1,NESNE * liste2)
{
/*verilen 2 listeyi birleştirir. Liste2 bu fonksiyon içinden yaratılır
eğer liste 1 null ise geriye liste2 döndürülür.*/
NESNE * gecici1;
NESNE * gecici2;

if (liste1!=NULL)
{

gecici1=liste1;
gecici2=liste2;

while(gecici1->ileri!=liste1)
{
gecici1=gecici1->ileri;
}

gecici1->ileri=gecici2;
gecici2->geri=gecici1;

while(gecici2->ileri!=liste2)
{
gecici2=gecici2->ileri;
}

liste1->geri=gecici2;
gecici2->ileri=liste1;

return liste1;

}

else
{
printf("\n\nDIKKAT! ˜lk liste null de§erine sahip! Bu durumda geriye dönen 2.listedir");
getch();
return liste2;

}
}




int getkey(void)
{
/*menüde ok tuşları enter ve esc karakterini almak için kullanılır*/
/* H. Paul Roach, Morgan State University , http://www.phanderson.com/C/getkey.html */
union REGS in, out;
in.h.ah = 0x08;
int86(0x21, &in, &out);
if (out.h.al == 0)
{
return(getkey()+0x100);
}
else
{
return(out.h.al);
}
}

void PrintMenuSelection(int sel_number)
{
/*aktif menü seçeneğini işaretler*/
int col;
int i;

col=7+sel_number;

for(i=21;i<=54;i++)
{
gotoxy(i,col);
printf("%c",219);
}

PrintMenuText();
}

void ClearMenuSelections()
{
/*menü seçimlerini 0lar*/
int col;
int i;

for(col=8;col<=18;col++)
{

for(i=21;i<=54;i++)
{
gotoxy(i,col);
printf(" ");
}

}

}


void PrintMenu()
{
/*menü borderlarını basar */
int i;
clrscr();


/* menuyu yazdir */
gotoxy(20,2);
printf("Veri Yaplar ™devi 1 - Hseyin Uslu");
gotoxy(16,3);
printf(".:: ------------------------------------ ::.");

gotoxy(20,7);
printf("%c",201);
for(i=1;i<=34;i++)
{
printf("%c",205);
}
printf("%c",187);
for(i=1;i<=11;i++)
{
gotoxy(20,7+i);
printf("%c",186);
gotoxy(55,7+i);
printf("%c",186);

}
gotoxy(20,19);
printf("%c",200);

gotoxy(21,19);
for(i=1;i<=34;i++)
{
printf("%c",205);
}
printf("%c",188);


}

void PrintMenuText()
{
/*menü textlerini yazdırır*/
gotoxy(32,8);
printf("Liste Yarat");

gotoxy(31,9);
printf("Listeyi Yazdr");

gotoxy(31,10);
printf("Listeyi Srala");

gotoxy(31,11);
printf("Yeni Node Ekle");

gotoxy(34,12);
printf("Node Sil");

gotoxy(34,13);
printf("Member()");

gotoxy(34,14);
printf("Locate()");

gotoxy(34,15);
printf("Count()");

gotoxy(29,16);
printf("Listeleri BirleŸtir");


gotoxy(1,4);
printf("Menüde gezinmek için aşağı, yukarı ok tuşlarını, seçim için Enter'ı kullanınız\n");
gotoxy(20,5);
printf("Programdan çıkmak için ESC'e basınız");
}


ee++
13/11/2002, 23:35
Yine ağır eleştiriler: :)

1- Kod gereksiz olarak uzun. (Aslında biraz da Ceviz sündürüyor.) Bir öneri: Bu tür Menu programlarında 10 tane 'if' ile yapılacak işi belirlemek yerine İşlev Göstergelerini (Function Pointers) kullanmak yakışıklı olur.

2- Kod standartlara uygun değil. Özellikle gotoxy gibi işlevleri kullanmamanı öneririm. Kodun tamamen DOS ve TC bağımlı, Linux'ta derlenmez. Linux'ta derlenmeyen seyi napcaz ki.. :)

3- Dil tarzanca.. :D (Bu konuda tartismayalim :) ) Hem kod, hem menu.. :) (Node: Düğüm)

Bir de su disaridan aldigin kodun amacini aciklar misin, fazla inceleyemedim.

RaiST
13/11/2002, 23:43
acip yoğun cevaplar:)

1- function pointers kullanmak dediğin gibi çok mantıklı
a) hoca / asistan kodu çaldığını düşünecektir hemen

2- ewt conio.h clrscr() gotoxy()... :)

3- türkçemiz pek iyi değil.. :) temp yerine türkçe bişiler bulalım dedik "geçici" bulduk :)

4- dışardan aldığım kod, bir key darbesinin ardından bu extended keyin değerini geri döndürüyor..aşağı yukarı ok tuşu olayları..
aslında şu var: bu fonksiyon olmadan daha önce bir menü sistemi hazırlamıştım.. bu fonksiyonda ki gibi dos bağımlılığıda fazla değildi. ama zaman yetersizliğinden bunu kullandım..

not 5: yazılan bütün bu kodlarda amaç kendinizi hocaya iyi göstermek olduğu için "ne kadar iyi , güzel yazdığınız değil", hocanın "beğenip beğenmemesi önemli".
eğer hoca yapacağım optimizasyon / iyileştirme / standartlara uygun kod yazmama artı puan verse en azından diğerlerine göre farkını anlasa , zamanımı kullanırım. ama malasef "çalışan her kod" onlar için aynı olduğundan sınav haftama 1 hafta kala yazdığım bu kodlarda; 1 satırı birdaha düşünmeden yazıyorum..
bundan dolayıdır ki birçok hata , yanlış, standartlara uymama durumu söz konusu. ama yinede sanırım birilerini başlangıçta işine yarayabilir

ee++
13/11/2002, 23:55
Orjinal mesajı gönderen RaiST
ama yinede sanırım birilerini başlangıçta işine yarayabilir

Bu olmadi, neden insanlara sanki ortalikta hic kod yokmus gibi sorunlu kodlar (aman darilma!) ile yol gosterelim? Yani dedigim gibi sen alinma, sadece genel dusuncemi soyluyorum. Yoksa buraya bu tip kodları koymak tabi ki cok guzel.

Ayrıca ok tuslarinin oldugu gibi ozel karakterlerin kodlarini almak icin ole elin gavurunun koduna filan gerek yok. Eger getch() ile bir cozum istersen:

ch = getch();
if(ch == 0)
{
ch = getch();
switch(ch)
{
case 72: /* bu bir okun kodu idi */ break;
case 80: /* bu da baska bir okun idi sanirim */ break;
/* vesaire */
}
}


Anlayacagin uzre, ozel tuslar iki kod dondurur, birincisi her zaman 0 olur. Ikincisi ise o tusun kodu.

Kolay gelsin.i

RaiST
14/11/2002, 00:06
herşeyden önce teşekkür ederim ee++.
şimdi gidip sen oo raist mükemmel kod yazmışsın diyip , kodda bulunan hataları es geçmiş olsan benim ve diğer arkadaşların zararına oldu..

ben senin mesajlara cevap yazdğını görünce sevindim zaten..
neden? çünki kodum incelenecek ve bende kendi gözümle göremediğim hataları görecektim...

yaptığınız işler üzerinde eleştiriler almak bence çok iyi bir durum. niye? çünki kendinizi geliştirmeniz için bir fırsat sunmaktadır.
sizin belkide 1 ay araştırıp düzeltebileceğiniz bir hatayı bir arkadaş çıkığ 5 dakkikada söyleyebilir...

ama şu noktayı vurgulamak istiyorum..
hatalı / sorunlu kodun paylaşılması bence tamamende yanlış bir olgu değildir..
yeni başlayan biri bu kodu çekip çalıştırdığında önce çalıştığını görecektir.. bu konularda kendini geliştirmeye devam ederse ilerde sorunların farkına varacak ve demekki şöyle kullanım yapmak yanlış diyecektir.
doğruya gidebilmek için yanlışları görmek gerekir.
+ yeni başlayan birine 100% hatasız kod vermek ona ne kazandırır?
Bakar koda iyi herşey çalışı9or der kapatır. Ama biryerde hataların olduğunu bildiği durumda sanırım bu onu araştırmaya iter.

mesela şöyle düşünelim..

yarın veri yapıları sınavınız var.. pek birşey bilmiyorsunuz..
-1. şıkta önünüze %100 hatasız kod veriyorlar.
yapacaığınız şey büyük ihtimalle kodu ezberlemek olur..
küçük değişiklerde ise koda anlamsızca bakmanız içten bile değildir.
-2. size verilen kodda hata olduğu söyleniyor. bu durumda yapmanız gereken daha hatasız bir kod araştırmaktır. hatasız kodu bulunca, birşekilde bu konuda nasıl hatalar olabildiğini görmüş oluyor ve bu hatalarla karşılaşma sansınızı en aza indiriyorsunuz..

neyse sanırım konu dağıldı..

bu arada ee++ extented keys kodu için sağol..
:)

ee++
14/11/2002, 00:09
Sorun yok. :) Devam..

RaiST
14/11/2002, 00:14
:) bu C bölümünü iyice hareketlendirelim..

benimde C'de gitmem gereken daha çok yol var.. bu bölüm nekadar hareketli olursa paylaşım o kadar çok olur

hadi bakalım hareket zamanı

ee++
14/11/2002, 00:26
Bende bu tip kodlardan sürüyle var. Ama hepsi buraya konacak cinsten degil. Kimisi proje halinde, yani cok kutuklu, kimisi cok ozel amacli, kimisi cok agir.. Mesela assembly ile fonksiyon grafigi cizim programi veya C ile 8088 islemci simulatoru gibi programlar da var ama buraya olmaz :) Belkim yeniden temiz bi kac kod yazariz..