Stack Yapılarını Gerçekleme // C

Başlatan sem, 23 Ağustos 2011 - 02:10:00

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

sem

Stack nedir; bir nevi senkronizasyon amaçlı sayılabilecek bir veri yapısıdır. LIFO mantığı ile çalışır (Last in First Out). İnternette konuyu araştırdığınızda karşılacağınız en çok örnek; tabakların dizilmesinden sonra; en son koyduğumuz tabağı ilk olarak alacağımızdır, ki doğrudur da (NŞA'da diyelim, yoksa tabii ben de bir kaç tabağı kaldırıp alttakini alabilirim).

mantığınıza yatan her hangi bir şekilde gerçekleyebilirsiniz.

yapı{
başlangıç adresi;
güncel adres (current)
uzunluk
}

Bu şekilde iki gösterici bir uzunluk birimi ile gerçeklenebilir. ki vereceğim örnekte de bu biçimde gerçeklenmiş olacak. Tabii bu zorunlu bir yapı değil...

Burada yapı oluştururken ki amacımız; verileri yerleştirip, en son koyduğumuzu alabileceğimiz her hangi bir yapı oluşturmak. Örneğin şöyle bir yapımız olsun;
yapı{
başlangıç adresi
index
uzunluk
}

Yani güncel gösterici yerine bir tane daha sayı koyup; (başlangıç adresi + index) şeklinde yine güncel adresi elde edebiliriz. Yani hangisi kolayınıza giderse o şekilde yapabilirsiniz. Benim çalıştığım kaynakta ilk verdiğim yapıdan anlatıldığı için o benim daha kolayıma geldi....


Örnek kodları vermeden önce biraz daha açalım konuyu;
stack yapısını gerçeklemek için bir yapı oluşturacağız. Bu yapının desteklemesi gereken konular;
* Stack içerisine yeni eleman eklenebilmelidir
* Stack içerisinden sondaki eleman daima çekilebilmelidir.

Bunlara bir stack yapsının bize zorunlu olarak vermesi gereken yani yapısının var olma sebebi olarak bize sunması gereken özellikler. Siz de tabii ek olarak bir takım özellikler ekleyebilirsiniz ya da stack yapısını uygulamanıza göre özelleştirebilirsiniz.

main.c
/*
* main.c
*
*  Created on: 23 Aug 2011
*      Author: sem0900
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "my_stack.h"

BOOL call_add_item(const int age, const char* name, const char *surname,  _mystack *mystack)
{
_person person;
person.age = age;
strcpy(person.name, name);
strcpy(person.surname, surname);

return add_item_to_stack(mystack, person);
}

int main()
{
_mystack *mystack;

if((mystack = initialize_stack(15)) == NULL)
exit(EXIT_FAILURE);

if(!call_add_item(25, "Semetey", "Coşkun", mystack))
puts("add_item de hata");

if(!call_add_item(26, "Serhat", "Karaçal", mystack))
puts("add_item de hata");

if(!call_add_item(30, "Mahmut", "Güngören", mystack))
puts("add_item de hata");

if(!call_add_item(31, "Yakup", "Emmioğlu", mystack))
puts("add_item de hata");

if(!call_add_item(33, "Ayşe", "Tanrıverdi", mystack))
puts("add_item de hata");

if(!call_add_item(24, "Katip", "Gülyüzer", mystack))
puts("add_item de hata");


system("clear");
puts("Stack içerisinde bulunan kişiler:");
puts("");

const _person *person;
while((person = get_item_from_stack(mystack)) != NULL)
fprintf(stdout, "İsim: %s\nSoyisim: %s\nYaş: %d\n\n\n", person->name, person->surname, person->age);


puts("Stack boşaltılıyor");
destroy_stack(mystack);
return 0;
}



my_stack.h
/*
* my_stack.h
*
*  Created on: 23 Aug 2011
*      Author: sem0900
*/

#ifndef MY_STACK_H_
#define MY_STACK_H_

/*boolean*/
typedef int BOOL;
#define TRUE  1
#define FALSE 0


#define PUBLIC

/*structure*/
typedef struct _Person{
int age;
char name[25];
char surname[25];
}_person;


typedef struct _MYSTACK{
_person *begin_stack;
_person *current;
size_t size;
}_mystack;


/*functions*/
_mystack * initialize_stack(size_t);
BOOL isempty_stack(_mystack*);
BOOL isfull_stack(_mystack *);
BOOL add_item_to_stack(_mystack *, _person);
const _person *get_item_from_stack(_mystack *);
void destroy_stack(_mystack *);


#endif /* MY_STACK_H_ */


my_stack.c
/*
* my_stack.c
*
*  Created on: 23 Aug 2011
*      Author: sem0900
*/

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "my_stack.h"


////////////////////////////////////////////////////////

_mystack * initialize_stack(size_t size)
{
_mystack *mystack;

if((mystack = (_mystack *)malloc(sizeof(_mystack))) == NULL)
return NULL; //malloc failure

if((mystack->begin_stack = (_person *)malloc(sizeof(_person) * size)) == NULL){
free(mystack);
return NULL;
}

mystack->size = size;
mystack->current = mystack->begin_stack + size;

return mystack;
}

////////////////////////////////////////////////////////

void destroy_stack(_mystack *mystack)
{
free(mystack->begin_stack);
free(mystack);
}

////////////////////////////////////////////////////////

BOOL isempty_stack(_mystack *mystack)
{
if(mystack->current == mystack->begin_stack + mystack->size)
return TRUE;
else
return FALSE;
}

////////////////////////////////////////////////////////

BOOL isfull_stack(_mystack *mystack)
{
if(mystack->begin_stack == mystack->current)
return TRUE;
else
return FALSE;
}

////////////////////////////////////////////////////////

BOOL add_item_to_stack(_mystack *mystack, _person person)
{
if(isfull_stack(mystack))
return FALSE;

--mystack->current;

mystack->current->age = person.age;
strcpy(mystack->current->name, person.name);
strcpy(mystack->current->surname, person.surname);

return TRUE;
}

////////////////////////////////////////////////////////

const _person *get_item_from_stack(_mystack *mystack)
{
if(isempty_stack(mystack))
return NULL;

return mystack->current++;
}

////////////////////////////////////////////////////////





Derlemek için dosyaları kayıt ettiğiniz dizine uçbirimden gelerek aşağıdaki komutu verin (dosya isimlerine dikkat edin, ben yukarıda verdiğim isimlere göre komutu veriyorum)
gcc main.c my_stack.c -o stack




Programın çıktısı şu şekilde olacaktır;
Alıntı YapStack içerisinde bulunan kişiler:

İsim: Katip
Soyisim: Gülyüzer
Yaş: 24


İsim: Ayşe
Soyisim: Tanrıverdi
Yaş: 33


İsim: Yakup
Soyisim: Emmioğlu
Yaş: 31


İsim: Mahmut
Soyisim: Güngören
Yaş: 30


İsim: Serhat
Soyisim: Karaçal
Yaş: 26


İsim: Semetey
Soyisim: Coşkun
Yaş: 25


Stack boşaltılıyor


main.c içerisindeki sıraya bakarsanız, ekleme sırası ile okuma sırası tamamen zıt olarak geliyor. Bu stack yapısının özelliğinden kaynaklanıyor, başta da söylediğimiz gibi.

Kullanım alanlarına örnek verip bırakayım;
Örneğin bir iskambil oyunu yapacaksanız; dağıtılan kartlardan seçen kullanıcı en sonuncuyu çekmek zorunda kalacak, ya da bazı biçimleri parçalamak ( parse ) için de stack yapıları kullanılıyor.


EK: Sanırım Türkçe karşılığı yığıt oluyor fakat emin olamadığım için biraz da terim gibi kullanıldığı için bu şekilde kullandım.


NOT: Program sadece kod örneği amaçlı olduğu için, herhangi bir teste tabi tutulmamıştır. Yanlış gören arkadaşlar başlık altında paylaşırsa, düzeltirim.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

alquirel

Paylaşım için teşekkürler.

Alıntı Yap
EK: Sanırım Türkçe karşılığı yığıt oluyor fakat emin olamadığım için biraz da terim gibi kullanıldığı için bu şekilde kullandım.

Ben şimdiye kadar hep yığın olarak biliyordum. Yığıtı ilk defa duydum.

Bir de bunun alternatifi olan Queue (Kuyruk) kullanımı ve bu ikisinin kullanım alanlarının daha fazla örnekleri ile ilgili bir belge daha hazırlanabilir ;)
(Zahmet olmazsa :D)

sem

Aynen yığını ben de duymuştum ama yığıt olarak da karşılaştım nette =)


Bağlı listeler ile kuyruk yapısı örneği için bu ayki SUDO'yu bekliyorum =)

Aslında fark eden bir şey olmaz fakat gönlüm önce SUDO'da yayınlanmasından yana. O nedenle forumdan önce SUDO'da yayınlanmasını bekliyorum =)

Dinamik olarak büyüyen, bağlı listeler ile kuyruk yapılarının gerçeklenmesi ile ilgili bir örnek kod vereceğim SUDO'da. Aslında asıl konu Dizin içeriğini elde etmek olsa da programlama ile ilgili konuları örnek yapmadan geçmek istemiyorum...

O nedenle bir tane çok basit bir örnek, bir tane ise ileri seviye sayılabilecek bir örnek olacak SUDO'da. =) Hatta kuyruk yapısının biraz daha özelleştirilmişi olacak anırım.. Sadece ilk yerleştirilenden başlayıp sırası ile elde etmek yerine, önceki & sonraki şeklinde dolaşılan bir şeyler var aklımda... Yani kuyruk yapısının güzelliği ve çift bağlı listenin avantajını kullanacağım diyelim =)

İyi reklam yaptım ama =)


EK: Tabii daha sonra detaylıca da bir anlatım yapılbilir iki veri yapısı hakkında da.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

alquirel

Alıntı yapılan: sem0900 - 23 Ağustos 2011 - 02:35:39
...
İyi reklam yaptım ama :)
...

Yakışır hocam ;)
Aslında çok imreniyorum senin bu çabalarını gördükçe ama şu tembelliği bir türlü atamıyorum üzerimden.
(Sözüm söz, unutmadım :D)