• Sonuç bulunamadı

Veri Yapıları. Kuyruk (Queue)

N/A
N/A
Protected

Academic year: 2022

Share "Veri Yapıları. Kuyruk (Queue)"

Copied!
61
0
0

Yükleniyor.... (view fulltext now)

Tam metin

(1)

Kuyruk (Queue)

Veri Yapıları

(2)

Kuyruk Yapısı

Kuyruk Yapısı da yığın kadar basit bir veri yapısıdır.

Yığından farkı, kuyruğa ilk giren elemanların ilk önce işlenmesidir.

Yani hizmet istekleri listenin sonuna eklenir. Bu

nedenle, First In First Out (FIFO) saklama olarak da tanımlanır.

Kuyruk aslında bir bekleme dizisidir.

Belirli bir hizmeti almak isteyenler, geliş sırasına göre bir bekleme listesine yerleşirler.

Listeye ilk eklenen eleman, en önce hizmet alır, son

eklenen ise en son hizmet alır.

(3)

Kuyruk Yapısı (devam)

Yapıya iki noktadan erişim söz konusudur.

Yeni gelenlerin eklenecekleri konumu işaretleyen bir son işaretçisi (son).

Hizmet alma sırası geleni belirlemek üzere bir baş (bas) işaretçisi.

bas

A1 A2 A3 A4

son

Kuyruk elemanları sadece baş taraftan çıkarılır, ve yeni gelen elemanlar daima sona eklenir.

(4)

Uygulama alanları

Bilgisayar sistemlerinde kuyrukların birçok uygulama alanları vardır:

Tek işlemcili bilgisayarlar bir anda sadece tek kullanıcıya hizmet verebilirler. Kullanıcı istekleri bir kuyruk

yapısında tutulur.

İşletim sistemlerinde birçok zamanlama işlemi kuyruk yapısı kullanılarak yapılır.

Bir yazıcıya yazdırma işlemi yine benzer yolla bir kuyruk yapısı kullanılarak yapılır.

. . .

(5)

Kuyruk işlemleri

ekleme: Kuyruğun en sonuna yeni bir eleman ekleme işlemidir. Eklenen eleman kuyrukta en sondaki eleman haline gelir.

ekle(...) – enqueue (...)

çıkarma: Kuyrukta en ön sırada yer alan elemanı,

kuyruktan çıkarma işlemidir. Bu elemanın arkasında bekleyen eleman, kuyrukta en ön sıraya yerleşir.

cikar() - dequeue()

boş olma durumunu kontrol etme: kuyruğun boş olup olmadığını kontrol etme işlemidir.

bosmu() – isempty()

(6)

Örnek

ekle(‘A’);

ekle(‘B’);

ekle(‘C’);

çıkar();

ekle(‘D’);

çıkar();

çıkar();

A B C

Bir kuyrukta sırasıyla şu işlemleri yapınız:

D

(7)

Dizi Kullanarak

Kuyruk Gerçekleme

(8)

1. Yöntem :

Dizi elemanlarının kaydırılması

Kuyruk başı işaretçisi her zaman dizinin ilk elemanı olsun.

Yeni eleman eklemek için son işaretçisi bir arttırılır.

Eleman çıkarılırken ise hep ilk eleman çıkarılır.

Ancak bu pahalı bir çözümdür: her eleman

çıkarıldığında, diğer tüm elemanlar birer

kaydırılmalıdırlar.

(9)

Örnek:

a c b

son baş

3 2 1 0

son baş

a c b

3 2 1 0

a çıktı

a c b

son baş

3 2 1 0

b çıktı

Dezavantaj : Her defasında dizinin tüm elemanları bir ileri kaydırılmalıdır.

(10)

2. Yöntem :

Çok büyük lineer dizi tanımlanması

Eleman eklemek için son işaretçisini bir arttır ve ekle.

Eleman çıkarmak için baş işaretçisini kullanarak elemanı oku ve işaretçiyi arttır.

Eğer çok büyük boyutlu bir dizimiz olsaydı problem şu şekilde çözülebilirdi:

int bas=0; int son=0;

char kuyruk[∞]; //infinite!

bool bosmu(){

return( bas == son );

}

void ekle( char x){

kuyruk[son++] = x ; }

char cikar(){

return( kuyruk[bas++] );

Mümkün değil!

(11)

Örnek:

a c b

son baş

3 2 1 0

c b a

son baş

3 2 1 0

a çıktı

a c b

son baş

3 2 1 0

b çıktı

c b a

son baş

3 2 1 0

c çıktı

a d c b

son baş

3 2 1 0

d eklendi

d c b a

baş son

3 2 1 0

d çıktı

Yeni ekleme yapılamaz!

Dizide yer yok görünüyor.

Dezavantaj: Gereksiz bellek kullanımı.

Kuyruk boş

(12)

#ifndef KUYRUK_H

#define KUYRUK_H

#define KUYRUKBOYU 10

typedef int KuyrukVeriTipi;

struct Kuyruk{

KuyrukVeriTipi eleman[KUYRUKBOYU];

int bas;

int son;

void olustur();

bool ekle(KuyrukVeriTipi);

KuyrukVeriTipi cikar();

bool bosmu();

};

(13)

void Kuyruk::olustur(){

bas=0;son=0;

}

bool Kuyruk::ekle(KuyrukVeriTipi yeni){

if(son<KUYRUKBOYU){

eleman[son++]=yeni;

return true;

}

return false;

}

KuyrukVeriTipi Kuyruk::cikar(){

return eleman[bas++];

}

bool Kuyruk::bosmu(){

return (bas==son);

}

Dizide yer olduğu halde, kuyruk dolu hatası döndürülebilir.

(14)

3. Yöntem : Çevrel Dizi

Diziyi doğrusal değil, çevrel olarak gerçekleriz.

Dizinin son elemanını ilk eleman izler.

Süreklilik sağlanır.

Farklı zamanlarda, dizinin farklı bölümlerinde elemanlar bulunacaktır.

Tam dolu olmadıkça “yer yok” mesajı alınmaz.

(15)

15

Çevrel Dizi

60 40 70

0 1 2 3 4 5 N-2 N-1 bas son

0

1 2

3

4 N-1

60 40 70

bas

son N-2 5

(16)

Çevrel Dizi olarak Gerçekleme

N elemanlı bir dizi çevrel olarak kullanılacak.

Kuyruk[0 … N-1]

N-1 indisinden 0 indisine geçiş isteniyor.

if (i == N-1)

i = 0;

else

i++;

i = (i+1)%N ;

(17)

Sınır Durumlar

son: son elemanı gösterir,

son işaretçisini bir arttır, atama yap.

baş: ilk elemanı gösterir,

okuma yap, baş işaretçisini bir arttır.

Eğer kuyrukta tek eleman var ise; baş ve son işaretçileri bu elemana işaret edeceklerdir.

a c x

son baş

i-1 i i+1

(18)

Sınır durum1) "Kuyruk boş"

En son eleman çıkarıldığı zaman, baş işaretçisi bir artıp sonu geçecektir.

a c x

son baş

i-1 i i+1

a c x

son baş

i-1 i i+1

Kuyruk boş koşulu:

baş == son+1

(19)

Sınır durum2) "Kuyruk dolu"

Eğer kuyrukta tek boş yer var ise, ve yeni bir eleman eklenirse yine baş işaretçisi sondan bir fazla

olacaktır.

0 1

2

baş (i+1) son

(i-1)

i

Dolu kuyruk koşulu: baş işaretçisi son’dan 1 fazla baş == son+1

(20)

Sınır durumlar için çözüm seçenekleri

Durum1 ve Durum2 olduğunda kuyruğun Boşmu yoksa Dolumu olduğunu ayırdetmek gerekir.

1. Dizi kapasitesini bir eksik tut. Bir alanı boş bırak.

2. Kuyruğun dolu olduğunu gösterecek bir lojik değişken kullan.

Veya kuyruktaki eleman sayısını içeren bir değişken kullan.

3. Özel indis değerleri kullanarak gerçekleme: Boş olma durumunu göstermek üzere işaretçilere özel değer ata.

İlk durum koşulları: bas=-1, son=-1

Kuyruk boşalınca ilk durum koşullarına geri dön.

Kuyruk doluysa son+1==bas

(21)

Özel İndis Değerleri Kullanılması

Başlangıç durumu: baş=0, son= -1

Kuyruk boş duruma geldiğinde, bu değişkenler başlangıç durumuna getirilir (reset)

Eğer kuyruk dolu ise, baş == son+1 and son != -1

(22)

BOŞ

Özel İndis Değerleri Kullanılması

0

1

2

3

5 4

0

1 2

3

5 4

DOLU

30 90

70 80

60 20

bas = 0 bas = 3

(23)

23

#define N 10 // Kuyruk boyu

typedef char KuyrukVeriTipi;

struct Kuyruk {

KuyrukVeriTipi dizi[N];

int bas;

int son;

void olustur();

bool ekle(KuyrukVeriTipi);

KuyrukVeriTipi cikar();

bool bosmu();

void kuyruk_yaz();

};

typedef struct KUYRUK Kuyruk;

( kuyruk_CevrelListe.cpp )

(24)

void Kuyruk::olustur() { bas=0; son=-1;

}

bool Kuyruk::ekle(KuyrukVeriTipi yeni) { if (son != -1 && (bas == (son + 1 ) % N) return false;

}

else {

son = (son+1)%N;

dizi[son] = yeni; // Kuyruğa ekle return true;

(25)

KuyrukVeriTipi Kuyruk::cikar() {

KuyrukVeriTipi eleman = dizi[bas];

if (bas == son)

bas = 0; son = -1;

else

bas = (bas + 1) % N;

return eleman;

}

bool Kuyruk::bosmu() {

return (bas==0 && son==-1);

}

(26)

void Kuyruk::kuyruk_yaz() { int i;

if ( bosmu() ) return;

cout << "KUYRUK (bas ile son arasi) :“ ; i = bas;

do {

cout << dizi[i] << " ";

if (i == son) break; // Stop loop i = (i+1) % N;

} while (1); // infinite loop }

(27)

int main() { Kuyruk k;

int islem;

char veri;

k.olustur();

secenekler();

cout << “Seciminiz : "; cin >> islem;

while ( islem != 3 ) { switch ( islem ) { case 1:

cout << "Bir harf girin : ";

cin >> veri;

k.ekle(veri);

k.kuyruk_yaz();

break;

case 2:

if (k.bosmu())

cout << "Kuyruk bos \n";

else

cout << “Cikarilan: " << k.cikar() ; k.kuyruk_yaz(); break;

default:

cout << "Gecersiz secim\n";

secenekler(); break;

} // end switch secenekler();

cout << “Seciminiz : ";

cin >> islem;

} // end while return 0;

} // end of main

(28)

void secenekler() {

cout << "KUYRUK ISLEMLERI (CEVREL DIZI ILE)\n"

<< "1. Ekle \n"

<< "2. Cikar \n"

<< "3. Son \n”;

}

(29)

Kuyruk boş

bas 0

29

0 1 2 3 4

son -1

• baş : dequeue işlemi için kullanılır.

• back: enqueue işlemi için kullanılır.

(30)

ekle(70)

0

70

• Özel Durum: Kuyruğa ilk defa eleman eklendi.

0 1 2 3 4

0

(31)

ekle(60)

70 60

31

0 1 2 3 4

bas 0

son 1

• son göstergesi 1 artırılır, sonra (60) verisi eklenir.

(32)

70 60 90

0 1 2 3 4

0 2

ekle(90)

(33)

70 60 90 40

33

0 1 2 3 4

bas 0

son 3

ekle(40)

(34)

60 90 40

• (70) verisi sıfırlanır, sonra bas göstergesi 1 artırılır.

0 1 2 3 4

1 3

cikar()

(35)

90 40

35

0 1 2 3 4

bas 2

son 3

• (60) verisi sıfırlanır, sonra bas göstergesi 1 artırılır.

cikar()

(36)

90 40 80

0 1 2 3 4

2 4

ekle(80)

(37)

20 90 40 80

37

• son göstergesi 1 artırılır ve wrap edilir.

0 1 2 3 4

bas 2 son

0

ekle(20)

(38)

20 50 90 40 80

0 1 2 3 4

2 1

ekle(50)

(39)

20 50 90 40 80

39

0 1 2 3 4

bas 2

• Özel Durum:

son + 1 == bas

• Ekleme yapılamaz!

son 1

ekle(100)

Kuyruk

dolu!

(40)

20 50 40 80

0 1 2 3 4

3 1

• bas göstergesi ile gösterilen eleman (90) diziden silinir.

cikar()

(41)

20 50 80

41

0 1 2 3 4

bas 4 son

1

• bas göstergesi ile gösterilen eleman (40) diziden silinir.

cikar()

(42)

20 50

0 1 2 3 4

0 1

• bas göstergesi ile gösterilen eleman (80) diziden silinir, ve bas wrap edilir.

cikar()

(43)

50

43

0 1 2 3 4

bas 1

son 1

• bas göstergesi ile gösterilen eleman (20) diziden silinir.

cikar()

(44)

0 1 2 3 4

0

• bas göstergesi ile gösterilen eleman (50) diziden silinir.

• Özel Durum : bas == son koşulu sağlandığı için göstergeleri -1 ve 0 yapılır.

-1

cikar()

Kuyruk

tekrar boş

(45)

Kuyrukların dizi üzerinde gerçeklenmesinin dezavantajı

Kuyrukların dizi üzerinde gerçeklenmesi de, yığınların dizi üzerinde gerçeklenmesine benzer problemler

oluşturur:

Kuyruk boyunun sabit olması, kuyruğa beklenenden fazla sayıda giriş yapılması durumunda hata ortaya çıkmasına yol açar.

Bu nedenle, kuyrukların liste üzerinde gerçeklenmesi

daha iyi bir çözümdür.

(46)

Bağlantılı Liste Kullanarak

Kuyruk Gerçekleme

(47)

Bağlantılı Liste kullanılarak gerçekleme

Dizi kullanarak gerçeklemenin getirdiği kısıtlamalar, bağlantılı listeler kullanılarak ortadan kaldırılabilir.

Kuyruğun başı listenin ilk elemanı, kuyruğun sonu da listenin son elemanı olacak şekilde tasarım yapılır.

Kuyruğa ekleme işlemi – listenin sonuna bir eleman ekleme,

Kuyruktan çıkarma işlemi – listenin başından bir eleman çıkarma şeklinde yorumlanır.

bas işaretçisi kuyruğun ilk düğümüne işaret eder. Çıkarma işlemi daima bas işaretçisi ile gösterilen düğümden yapılır. Bu nedenle kuyruktan çıkarma yapmak için listenin taranması ve silinecek düğümün aranması şeklinde bir durum yoktur.

son işaretçisi kuyruğun son düğümüne işaret eder. Ekleme işlemi daima son işaretçisi ile gösterilen düğümün arkasına yapılır. Bu nedenle kuyruğa ekleme yapmak için listenin taranması şeklinde bir durum yoktur.

Kuyruktaki düğümlerin alfabetik, nümerik vb. artan/azalan sırada olması gibi bir durum yoktur.

(48)

Kuyruk boş

bas son

• baş : dequeue işlemi için kullanılır.

• back: enqueue işlemi için kullanılır.

(49)

ekle(60)

49

• Listeye ilk defa düğüm eklendiği için bas ve son işaretçileri aynı düğüme işaret ediyor.

60

bas son

(50)

ekle(40)

• Yeni veri (40) sona eklenir.

bas son

(51)

ekle(50)

51

• Yeni veri (50) sona eklenir.

60 bas

40 50

son

(52)

cikar()

• Listenin başındaki düğüm (60) silinir.

bas

60 çıkarıldı son

(53)

cikar()

53

• Listenin başındaki düğüm (40) silinir.

50 bas

40 çıkarıldı son

(54)

cikar()

• Listenin başındaki düğüm (50) silinir.

• Kuyruk tekrar boş duruma geldi.

bas

50 çıkarıldı son

(55)

55

#ifndef KUYRUK_H

#define KUYRUK_H

typedef char KuyrukVeriTipi;

struct Dugum{

KuyrukVeriTipi veri;

Dugum *sonraki;

};

struct Kuyruk{

Dugum * bas;

Dugum * son;

void olustur();

void kapat();

bool ekle(KuyrukVeriTipi);

KuyrukVeriTipi cikar();

bool bosmu();

void kuyruk_yaz();

};

typedef struct KUYRUK Kuyruk;

#endif

( kuyruk_BaglantiliListe.cpp )

(56)

void Kuyruk::olustur(){

bas=NULL;son=NULL;

}

void Kuyruk::kapat(){

Dugum *p;

while (bas){

p = bas;

bas = bas->sonraki;

delete p;

} }

(57)

void Kuyruk::ekle(KuyrukVeriTipi yeni){

Dugum *yenidugum=new Dugum;

yenidugum->veri=yeni;

yenidugum->sonraki=NULL;

if(bas==NULL){

bas=yenidugum;

son=bas;

}

else{

son->sonraki=yenidugum;

son=yenidugum;

} }

(58)

KuyrukVeriTipi Kuyruk::cikar(){

Dugum *ustdugum;

KuyrukVeriTipi gecici;

ustdugum=bas;

bas=bas->sonraki;

gecici=ustdugum->veri;

delete ustdugum;

return gecici;

}

bool Kuyruk::bosmu(){

return bas==NULL;

}

(59)

void Kuyruk::kuyruk_yaz() { Dugum * tara = bas;

if (bosmu()){

cout << "Kuyruk bos \n";

return;

}

cout << "KUYRUK : ";

while (tara != NULL ) { cout << tara->veri;

tara = tara->sonraki;

} }

(60)

main()

int main(){

Kuyruk k;

k.olustur();

k.ekle('A');

k.ekle('B');

k.ekle('C');

k.kuyruk_yaz();

char c=k.cikar();

k.ekle('D');

k.ekle('E');

k.ekle('F');

c=k.cikar();

if(!k.bosmu()) k.cikar();

k.kuyruk_yaz();

k.kapat();

return 0;

}

(61)

Uygulamada Yapılacaklar

Kuyruk yapısı ile simülasyon

Referanslar

Benzer Belgeler

(d) Bir müşterinin sistemde harcadığı toplam ortalama zaman (dakika) (e) Kuyrukta bekleyen ortalama müşteri sayısı (saatte).. (f) Arabasını yıkatmaya gelen Büşra Hanımın o

Tablo 1’de gösterilen sonuçlara göre, mevcut 90 ilanın % 74’lük kısmı halkla ilişkiler elemanı ile halkla ilişkiler sorumlusu ve halkla ilişkiler uzmanı

Prof Abas Zaman-su, Kâmran Memedov, Habib Babayev Filoloji nemzedi (şimdi, ilimler doktoru A.İ.) İsa Habibeyli şair dramatur Lamzik Muhtar konuşup eser hakkında kendi

kayda geçirilerek il bazında vektörel veri tabanları hazırlanmıĢtır (Örnek, Tablo 2). A) SayısallaĢtırma: Ġlk aĢamada Harita Genel Komutanlığından satın alınan 1:25000

مسقأ(ردقيو فوذحم اهلعف ةيلعف يهف ةلمجلا ةرادصب مسقلا فورح تءاج اذإ ( مسقأ( ردقيو فوذحم اهلعف ةيلعف لمجلا نوكت قتشم مسقلا ةادأ تءاج اذإ

Geliştirilen taşınabilir kazı setinde mini disk ile yapılan kesme deneylerinden, konik keskilerle elde edilen spesifik enerji değerinin tahmin edilip edilemeyeceğini

The original research sample consisted of (400) male and female students of governmental secondary school (preparatory cycle) (Morning study) for boys and girls

The findings of the study for the dimensions taken out which reveal that for the dimension of teachers’ attitude towards inclusive education shown that a total of 24% of