You are on page 1of 29

TEMEL VERİ YAPILARI

VERİ YAPILARI VE UYGULAMALARI DeRSİ


1

İşaretciler (Pointer)
 İşaretçiler, bilgisayar belleğindeki belli bir adresi
gösteren ve gösterdiği bellek adresine erişimi sağlayan
değişkenlerdir.
 İşaretçilerin diğer değişkenlerden tek farkı başka bir
değişkenin bellek adresini içeriyor olmasıdır. Aşağıdaki
satır işaretçi bildiriminin genel yapısını göstermektedir:
veri-türü *değişken-adı;
Aşağıdaki işlem satırı ip1 adlı int bir işaretçi değişkeni
oluşturmaktadır:
int *ip1;
 İşaretçi ile işaretçiye bellek adresi atanan değişkenin
veri türü aynı olmalıdır.

1
İşaretçilere Değer Atanması
 * : Hangi işaretçi değişken adından önce kullanılırsa, o işaretçi değişkene adresi atanan
değişkenin değerini verir.
 & : Hangi değişken adından önce kullanılırsa, o değişkenin adresini verir.
main() {
int *ip1, id1;
id1 = 278;
ip1 = &id1;
/* id1 değerinin doğrudan yazılması */
printf("id1 değişken değeri: %d\n", id1);
/* id1 değişken değerinin dolaylı olarak yazılması */
printf("id1 değişken değeri: %d\n", *ip1);
/* id1 değişken bellek adresinin işaretçi yoluyla yazılması */
printf("id1 değişkeni bellek adresi: %p\n", ip1);
/* id1 değişken bellek adresinin & işlemcisi ile yazılması */
printf("id1 değişkeni bellek adresi: %p", &id1); }

İşaretçiler Yoluyla Değişkenlere Değer


Atanması
main()
{
int *ip1, *ip2, id1, id2; /* 1 */
ip1 = &id1; /* 2 */
ip2 = &id2; /* 3 */
id1 = 42; /* 4 */
*ip2 = 67; /* Dolaylı değer atama yöntemi */ /* 5 */
printf("id1 değişkeninin değeri: %d\n", *ip1);
printf("id2 değişkeninin değeri: %d\n", *ip2);
printf("id1 değişkeninin bellek adresi: %p\n", ip1);
printf("id2 değişkeninin bellek adresi: %p\n", ip2);
}

2
Diğer İşaretçi İşlemcileri ve İşlemci
Aritmetiği
 Bir işaretçi değere sadece tanımlandığı veri
türünden bir değer ekler veya çıkarabilirsiniz.
int *ip1;
ip1++ <====> ip1 = ip1 + (1*sizeof(int));

*ip1++; /* İşaretçinin gösterdiği bellek adresini


artırır. */
(*ip1)++; /* İşaretçinin gösterdiği bellek
adresindeki değişken değerini artırır. */

Diziler
Diziler programın çalışma zamanı sırasında da dinamik
olarak yaratılabilirler. Elde edilen alanın adresi bir
göstericiye atanırsa o bölge bir dizi gibi kullanılabilir.
Örneğin:
int *pi;
...
pi = (int *) malloc(sizeof(int) * 10);

C# ve Java’da diziler de sınıfsal bir biçimde temsil


edilmişlerdir. Bu dillerde diziler new operatörü ile dinamik
olarak yaratılmak zorundadır. Örneğin:
int[] a;
a = new int[10];

3
NYP ve Diziler
 C# ve Java'da dizi isimleri dizi nesnelerinin
adreslerine ilişkin referans belirtmektedir. Bu
dillerde bir dizi referansını şöyle düşünebiliriz:

İşaretçi ve Diziler
 C dilinde göstericiler ve diziler arasında yakın bir ilişki
vardır. Bir dizinin adı, dizinin ilk elemanının adresini
saklayan bir göstericidir. Bu yüzden, bir dizinin herhangi
bir elemanına gösterici ile de erişilebilir. Örneğin:
int kutle[5], *p, *q;
şeklinde bir bildirim yapılsın. Buna göre aşağıda
yapılan atamalar geçerlidir:
p = &kutle[0];
/* birinci elemanın adresi p göstericisne atandı */
p = kutle;
/* birinci elemanın adresi p göstericisne atandı */
q = &kutle[4];
/* son elemanın adresi q göstericisne atandı */

4
İşaretçi ve Diziler
 Ayrıca, i bir tamsayı olmak üzere,
kutle[i]; ile *(p+i);
aynı anlamdadır.
Bunun sebebi, p göstericisi kutle dizisinin başlangıç
adresini tutmuş olmasıdır. p+i işlemi ile i+1. elemanın
adresi, ve *(p+i) ile de bu adresteki değer hesaplanır.
*p+i; /* p nin gösterdiği değere (dizinin ilk
elemanına) i sayısını ekle */
*(p+i); /* p nin gösterdiği adresten i blok ötedeki
sayıyı hesapla */

Örnek
# include <stdio.h>
# include <conio.h>
int main ()
{
int *p,num[5]={4,5,6,7,8},j;
clrscr();
p=num;
printf("Elements Address");
for (j=0;j<5;j++)
printf ("\n %3d %7u", *(p+j),(p+j));
}

10

5
Örnek
int main(int argc, char *argv[]) {
int sayi[5]= {2, 4, 5, 6, 10};
int i, *ptr;
ptr = sayi;
for (i = 0; i<5; i++){
printf("\n sayi = %d", *ptr);
ptr++;
}
}

11

Örnek
int main(int argc, char ptr++;
*argv[]) }
{ ptr--;
int ch[5]; for (i = 0; i<5; i++)
int *ptr=ch; {
int i; printf("\n girilen sayı = %d
for (i = 0; i<5; i++) ", *ptr);
{ ptr--;
printf("\n sayı giriniz = "); }
scanf("%d", ptr); }

12

6
Matrislerde İşaretçi kullanımı
 iki boyutlu dizilerin gösterge değişkenlere atanma şekilleri için aşağıda
örnekler verilmektedir.
int x[3][4];
int *p1= &x[0][0];
ya da
int x [ 3 ] [ 4 ] ;
int *p1;
p1 = &X[0][0];
satırları aynı işlevi görmektedir. Yukarıda verilmiş bulunan örneklerin her
ikisinde de, iki boyutlu 3x4 büyüklüğündeki x tamsayı dizisi p1 gösterge
değişkenine atanmaktadır. Bu atama ile p1 gösterge değişkeni x dizisinin ilk
elemanının adresini tutmaktadır. Bu durumda dizinin i satırı ile j kolonunun
birleştiği noktadaki elemana
*(p + ( i * 4 + j))
satırı ile erişilir. Yukarıdaki satırda verilmiş olan 4 değeri her satırda bulunan
eleman sayısını göstermektedir.

13

Yapılar (Structures)
 Elemanları farklı türlerden olabilen ve bellekte ardışıl bir biçimde
bulunan veri yapılarına yapı (structure) denilmektedir. Yine buradaki
ardışıllık yapının başlangıç adresinin bilinmesi durumunda onun tüm
elemanlarına sabit zamanlı, yani O(1) karmaşıklıkta erişilmesini
sağlar.
 Yapı elemanları farklı türlerden olabildiğine göre hangi elemanın hangi
türden olduğunun da bir biçimde derleyiciye açıklanması
gerekmektedir. Yapı elemanlarının türlerinin ve isimlerinin derleyiciye
tanıtılması işlemine yapı bildirimi denilmektedir. Örneğin C/C++'ta bir
yapı aşağıdaki gibi bildirilir:

struct PERSON {
char name[32];
int no;
float weight;
};

14

7
Yapılar Neden Kullanılırlar?
1)Yapılar gerçek bir nesnenin ya da kavramın birbirleriyle
ilişkili birtakım özelliklerini temsil etmek için mantıksal
bir küme oluştururlar. Örneğin bu sayede biz bir tarih
bilgisini DATE isimli bir yapıyla, bir noktayı POINT isimli
bir yapıyla temsil edebiliriz. Bu tür temsiller soyutlamayı
artırarak algılamayı kolaylaştırmaktadır.
2) Yapılar farklı türlerden çok sayıda bilgiyi fonksiyonlara tek
bir parametre olarak geçirmemize olanak sağlarlar.
void Foo(char *name, int no, float weight);
...
Foo("Ahmet Kaya Aslan", 123, 78.3);
void Foo(const struct PERSON *per);
...
struct PERSON per = {"Ahmet Kaya Aslan", 123, 78.3};
Foo(&per);

15

Örnek
struct s_yapi printf ( " Bir karakter giriniz:");
{ scanf ( "%c", &s.ch);
int i; printf ( " Herhangi bir double sayi
char ch; giriniz:");
double d; scanf ( "%1f", &s.d );
char str[80]; printf ( " Bir karakter dizisi
giriniz:");
};
scanf ( "%s", &s.str);
struct s_yapi s;
printf("\n girilen yapi değerleri :");
int main(int argc, char *argv[]) {
printf ( "\n %d %c %lf %s "0, s.i,
s.ch, s.d, s.str);
printf ( " Bir tam sayi giriniz:"); }
scanf ( "%d", &s.i);

16

8
Hizalama (Alignment) Kavramı
 Bu noktada yapılarla ilgili önemli bir anımsatma yapmak
istiyoruz: C/C++’ta yapı elemanları derleyici tarafından
aralarında boşluklar olacak biçimde belleğe
yerleştirilebilmektedir. Yapı elemanlarının ve genel olarak
nesnelerin belirli sayının katlarında olacak biçimde belleğe
yerleştirilmelerine hizalama (alignment) deniyor.
 Pek çok modern işlemci, eğer nesneler bellekte belli sayının
katlarında bulunuyorsa (örneğin 32 bit işlemcilerde 4'ün
katlarında) onlara daha hızlı erişebilmektedir.
struct SAMPLE {
char a;
int b;
short c;
};

17

Birlikler (Unions)
 Elemanların çakışık olarak yerleştirildiği veri
yapılarına birlik (union) denilmektedir. Birlikler
C/C++’ta yapılara benzer bir sentaksla
bildirilirler. Örneğin:

union SAMPLE {
char a;
int a;
double c;
};

18

9
Birlikler (Unions)
 Bir birlik için birliğin en büyük elemanı kadar
yer ayrılır. Yukarıdaki örnekte birliğin en büyük
elemanı double olduğundan s isimli birlik
nesnesi için toplam 8 byte yer ayrılmıştır. Birlik
elemanlarının çakışık yerleştirildiğine dikkat
ediniz. Elemanların bu biçimde çakışık
yerleştirilmesi onların birinde değişiklik
yapılması durumunda hepsinin bundan
etkileneceği anlamına gelir.

19

Birliklere Neden Gereksinim


Duyulmaktadır?
1) Farklı bilgilerden herhangi birinin ekonomik bir
biçimde tutulması gerektiği durumlarda. Örneğin
bir kişinin T.C. numarası ya da adresi yeterli ise bu
bilginin çakışık olması yer kazancı sağlar. Tabi
böylesi durumlarda hangi bilginin dolu olduğunun
ayrıca bir bayrakla tutulması gerekecektir.
2) Bütünü parçalara ayırmak veya parçalardan bütünü
oluşturmak için. Örneğin 4 byte işaretsiz bir
tamsayı türünün byte'larını ayrı ayrı oluşturup onu
bir bütün olarak almak ya da bütünü oluşturup
herhangi bir byte'ını elde etmek için şöyle bir birlik
oluşturulabilir:

20

10
Birliklere Neden Gereksinim
Duyulmaktadır?
union DWORD dw;
union DWORD {
unsigned int dword;
struct {
unsigned char b0, b1, b2, b3;
} bytes;
};

dw.bytes.b0 = 0x12;
dw.bytes.b1 = 0x34;
dw.bytes.b2 = 0x56;
dw.bytes.b3 = 0x78;

printf("%x\n", dw.dword);

/* Litte Endian: 0x78563412, Big Endian: 0x12345678 */

21

Sınıflar (Classes)
 Sınıflar nesne yönelimli programlama (object
oriented programming) tekniğinin yapı taşlarını
oluşturan veri yapılarıdır.
 Nesne yönelimli programlama tekniğinin tek bir
cümleyle tanımını yapmak olanaksız olsa da eksik bir
biçimde "sınıflar kullanılarak program yazma
tekniğidir" denebilir.
 Sınıflar nesne yönelimli programlama tekniğinde belli
bir konudaki gerçek bir nesneyi ya da kavramı temsil
etmek için kullanılırlar. Bir proje nesne yönelimli olarak
modellenecekse önce projeye konu olan bütün gerçek
nesneler ve kavramlar sınıflarla temsil edilir; sonra
sınıflar arasındaki ilişkiler belirlenerek kodlama yapılır.
Sınıflar hem veri elemanlarını hem de fonksiyonları
tutan veri yapılarıdır.

22

11
Sınıflar (Classes)
 Sınıflar C'deki yapıların fonksiyon içeren
biçimlerine benzetilebilir. Sınıfların veri elemanları
(data'ları) sınıfların fonksiyonları tarafından ortak
bir biçimde kullanılırlar. Sınıfların veri eleman
organizasyonu tamamen yapılara benzemektedir.
Sınıfların fonksiyonları sınıf nesnesi içerisinde yer
kaplamazlar, fonksiyonlar mantıksal olarak sınıfla
ilişkilendirilmişlerdir.
 Bir sınıf fonksiyonlara ya da veri elemanlarına sahip
olmak zorunda değildir. Sınıfların veri elemanları o
dillerin standartlarında açıkça belirtilmese de tıpkı
yapılarda olduğu gibi nesne içerisinde ardışıl bir
biçimde yerleştirilirler.

23

Sınıflar

class Sample {
public:
void Foo();
void Bar();
void Tar();
//...
private:
int m_a;
int m_b;
int m_c;
};

24

12
Kaynaklar
 Veri Yapıları ve Algoritmalar, Dr. Rıfat
ÇÖLKESEN, Papatya yayıncılık
 Ahmet Yesevi Üniversitesi Ders Notları
 http://www.kaanaslan.com/resource/article/di
splay_article.php?id=94
 C & Data Structures, P. S. Deshpande, O. G. Kakde
 http://www.bilgigunlugum.net/cprog/c_isaretci
.html

25

ALGORİTMALAR

VERİ YAPILARI VE UYGULAMALARI Dersi


26

13
Algoritmalar nedir?

Algoritmalar
 Matematiksel ve bilgisayar programları için
algoritmalar, bilgisayar biliminin (yani computer
science) konusudur
 Bilgisayar bilimi, matematiğin bir bölümüdür
 Buradaki anlamda algoritmalar, bir matematiksel
problemin çözüm talimatı yada planıdır

27

Algoritmalar nedir?
 Matematiksel algoritmalar,
 Matematiksel bir soru var,
 Sorunun çözüm/amacına nasıl ulaşabileceğini
açıklayan detaylı bir plan, bu problemin
algoritmasıdır

28

14
Algoritmalar nedir?
 Daha genel anlamda algoritmalar, her hangi bir
sorunun detaylı çözüm planı olarak
düşünülebilir
 Sadece matematikte yada bilgisayar
programlamada değil, günlük hayatta hepimiz
bol bol algoritma kullanırız

29

Algoritma temsilleri
 Algoritma belirtmek için, çözüm planı/tarifi
belirli, biçimsel ve biri tarafından kolayca
anlanabilir şekilde tanımlanması gerekmektedir
 Önceki örnekler gibi, bir talimat liste şeklinde
sırayla tanımlanan algoritmalara sözde kod denir

30

15
Algoritma temsilleri
 Sözde kod, algoritmanın talimatları adım adım ve
biçimsel şekilde belirtmek için normal dil ifadeleri
kullanır
 Sözde kod, normal bilgisayar programlara kollayca
dönüştürülebilmesi için, algoritmaların temel
tanımları vermek için genellikle kullanılır

31

Sözde kod

32

16
Algoritma temsilleri
 Algoritmaların temsili için ikinci popüler yöntem
akış şemalarıdır
 Bu şekilde temsil edilen algoritmalara akış
şeması denir
 Akış şeması, algoritmanın talimat sırasını
veya algoritmanın işlem akışını belirtir

33

Sözde kod
 Example 1: Öğrencinin final notunu belirleyip
geçip geçmediğini belirleyen bir algoritma
yazınız. Final notu 4 notun ortalamasıdır

34

17
Pseudocode & Algorithm
Pseudocode:
 4 adet notu giriniz

 Notları toplayıp 4 e bölerek ortalamayı hesapla

 Eğer ortalama 50 den aşağı ise

Göster “BAŞARIZ”
değil ise
Göster “BAŞARILI”

35

Pseudocode & Algorithm


 Detaylı Algoritma
 Adım 1: Giriş M1,M2,M3,M4
Adım 2: ORT (M1+M2+M3+M4)/4
Adım 3: if (ORT< 50) then
Print “BAŞARISIZ”
else
Print “BAŞARISIZ”
endif

36

18
Akış Şeması
 Akış şeması; bilgisayar programlarının işlem
basamaklarını geometrik şekillerle gösteren şemadır.
 Bir başka tanım da; algoritmaların görsel elemanlarla
oluşturulmasıdır. Algoritma adımında belirtilen bir veya
bir grup işlem, geometrik bir şekil ile ifade edilir. Bu
şekiller standartlaşmış durumdadır.
 Akış şeması bir işin tamamlanması için gerekli adımların
çok daha iyi anlaşılmasını sağlayan görselliği sağlar.
 Programın akış yönü ve işlemler arası bağlantıyı çubuklar
ve oklar gösterir. Bazı işlemler için genel şekiller veya o
işleme ait özel şekiller kullanılabilmektedir.

37

Akış Şeması
Bir akış şeması
 Algoritma mantığını belirtir
 Bağımsız adımlar ve bağlantılarını vurgular

38

19
39

Karar Yapısı
 The flowchart segment below shows how a decision
structure is expressed in C++ as an if/else statement.

Flowchart C++ Code

NO YES if (x < y)
x < y? a = x * 2;
else
Calculate a Calculate a a = x + y;
as x plus y. as x times 2.

40

20
Tekrarlı Yapı
 The flowchart segment below shows a repetition structure
expressed in C++ as a while loop.

Flowchart C++ Code

while (x < y)

YES x++;
x < y? Add 1 to x

41

Case Structure

 The structure below indicates actions to perform


depending on the value in years_employed.

CASE
years_employed

1 2 3 Other

bonus = bonus = bonus = bonus =


100 200 400 800

42

21
Combining Structures
 This flowchart segment
shows two decision
structures combined. NO YES
x > min?

Display “x is NO YES
outside the limits.”
x < max?

Display “x is Display “x is
outside the limits.” within limits.”

43

Example

START
Step 1: Input M1,M2,M3,M4
Step 2: GRADE  (M1+M2+M3+M4)/4
Input
M1,M2,M3,M4
Step 3: if (GRADE <50) then
Print “FAIL”
else
GRADE(M1+M2+M3+M4)/4 Print “PASS”
endif
N IS Y
GRADE<5
0

PRINT PRINT
“PASS” “FAIL”

STOP

44

22
Algoritma temsilleri
• Algoritma, normalde belirli bir soru için geliştirilir ve
farklı sorular için farklı algoritmalara gerek vardır; bu
anlamda genel bir algoritma olamaz
• Ancak genel algoritma geliştirme stratejileri veya
birçok benzer soruyu çözen algortimalar olabilir
 Özyineleme (recursion)
 Böl ve fethet (divide and conquire)

 Açgözlü/yerel (greedy or local)

 Dynamik programlama (dynamic programming)

45

Algoritma türleri
Özyineleme (recursion)
• Çözüm adımları aynı işlemin tekrarlanması şeklindedir
• Sonuç aynı işlem yinelenen uygulamasıyla elde edilir

• Factöriyel özyinelemenin klasik örnektir:


 Faktöriyel – “n!=1*2*3*…*n”
 Özyineleme adımı: n!=n*(n-1)!
 Özyineleme uygulaması: F(sayı)=sayı*F(sayı-1)
 Bunun uygulanması faktöriyeldir, yani F(n)=n*F(n-1)=n*(n-1)*F(n-
2) ...=n*(n-1)*(n-2)*...*1

46

23
Algoritmaların temel türleri
Böl ve fethet (divide and conquire)
• Problem birkaç daha küçük probleme bölünebilir
• Daha küçük problemlerin çözümü daha çok kolaydır
• Orijinal problem, altproblemlerin çözümlerini kullanarak
daha hızlı çözülebilir

• Sıralama böl-ve-fethet yaklaşımın klasik örneğidir


 Bir n-elemanlı dizi sıralanması n2 karşılaştırma işlemi gerekir
 Diziyi iki n/2-elemanlı parçaya bölüp parçaları ayrı ayrı sıralayıp
böylece 2*(n/2)2 = n2/2 karşılaştırma işlem olacak
 Parçaları geri birleştirip orijinal dizi n2/2+n işlemle sıralanacaktır

47

Algoritmaların temel türleri


Açgözlü/yerel (greedy/local)
• Genellikle optimizasyon problemlerinde kullanılan
yaklaşım, yani bir soru için en uygun (optimal olan) cevabı
bulmak gerekmektedir
• Böyle cevabı adım adım ararken, tüm adımlarda o adımda
en iyi olarak görünen seçimi yapmak gerekmektedir

• Açgözlü/yerel yol seçme örneği:


 Evden çıktığımızda okula en yakın yere giden dolmuşu bineriz
 Durakta inince, tekrar okula en yakın yere giden dolmuşu bineriz
 ... VB
 Bu yol seçme sorunun açgözlü çözümüdür

48

24
Algoritmaların temel türleri
Dinamik programlama (dynamic programming)
• Bir tür optimizasyon problemlerinde kullanılan yaklaşım
• Bütün olabilir cevapların uygunluğu bir özyineleme kullanarak
hesaplanabilirse, dinamik programlama uygulanabilir

• Dinamik programlama ile yol seçme örneği


 Fikir:
Bütün duraklar için o duraktan okula ulaşmak için optimal gereken zamanı
t(DURAK) olsun;
 t-hesaplanması:
 Okulda olan A durağında t(A)=0
 A durağına bağlı duraklar için, t(B)=min(t(A)+t(A←B))
 Bu adım bütün duraklar için uygulayınca, bütün duraklar için t(B) elde edilebilir
 A’dan başlayınca, bütün bağlı duraklar adım adım inceleyip ona optimal ulaşma
zamanı seçin, bu duraklar için özyineleme şekilde ona bağlı duraklar için t(B)
hesaplayın, vb

49

Algoritmaların temel türleri

10 dk
5 dk
15 dk
10 dk 10 dk

10 dk Ev
5 dk 5 dk
5 dk
15 dk
Okul 5 dk 5 dk

15 dk
10 dk

50

25
Algoritmaların temel türleri
15=min(5+10,10+10)
5=0+5

10 dk 1
5 20
5
15 dk
5 dk 10 dk 10 dk

10 dk 1 Ev
0
0 5 dk 5 dk 30
5 dk
15 15 dk 25
Okul 5 dk 5 dk
5 20 30
15 dk
10 dk

51

Algoritmaların temel türleri


Bu şekilde bulunmuş en hızlı
yolun tam zamanı 5+10+10+5=30
dk

10 dk
5 dk 5 15 20
15 dk
10 dk 10 dk

10 dk 10
Ev
0 5 dk 5 dk 30
5 dk
15 15 dk 25
Okul 5 dk 5 dk
5 20 30
15 dk
10 dk

52

26
Algoritmaların temel türleri
Fark edin ki açgözlü yolun
zamanı 15+5+5+10=35 dk

10 dk
5 dk 5 15 20
15 dk
10 dk 10 dk

10 dk 10
Ev
0 5 dk 5 dk 30
5 dk
15 15 dk 25
Okul 5 dk 5 dk
5 20 30
15 dk
10 dk

53

Algoritma analiz temelleri


• Herhangi algoritma biri tarafından uygulanması
düşünülmektedir (örneğin, bir kişi, bilgisayar, vb)
• Bu açıdan, herhangi algoritmanın çok önemli olan bir
noktası algoritmanın işlemlerini gerçekleştirmek için
gereken zaman ve herhangi diğer önemli maliyetidir

54

27
Algoritma analiz temelleri
• Algoritmanın işletme zamanı kesin durumuna bağlıdır
(örneğin, durakların sayısı, dizinin boyutu, ...)
• Bunun gibi kesin “durumlara” algoritmanın girişi
denir
• Böylece, algoritmaların işletme zamanı ve diğer
maliyetlerinin girişine bağlı dır

55

Algoritma analiz temelleri


• Algorıtma analizinin amacı, belirli bir giriş için
algoritmanın zaman ve bellek gereksinimleri
belirtmektedir
• Algoritmaların zaman ve bellek gereksinimleri giriş
boyutuyla genellikle artır
• Giriş boyutuna genellikle “n” denir
• Böylece “n”, girişin boyutunu herhangi şekilde belirten
bir niceliktir – sıralanacak sayıların sayısı, yol için
olabilir durak sayısı, vb

56

28
Kaynaklar
 Veri Yapıları ve Algoritmalar, Dr. Rıfat ÇÖLKESEN,
Papatya yayıncılık
 Ahmet Yesevi Üniversitesi Ders Notları
 http://www.kaanaslan.com/resource/article/displa
y_article.php?id=94
 C & Data Structures, P. S. Deshpande, O. G. Kakde
 http://www.bilgigunlugum.net/cprog/c_isaretci.ht
ml
 http://yumishch.me/MIT503.html
 https://www.mustafayemural.com/c-my000012/

57

29

You might also like