Bir Stack<T> bir yığındır: öğeleri Push ile en üste koyar ve Pop ile en üstten alırsınız, böylece son giren ilk çıkar (LIFO). Yalnızca en üst erişilebilirdir ve üzerindeki her işlem sabit zaman alır.
Push, Pop ve Peek
Çıktı:
On top: green
Count: 3
Took green
On top: red
Took red
Took blue
Count: 0
green en son push edildi, bu yüzden ilk o çıkar. Peek stack'i değiştirmeden en üstü döndürür; Pop'un size ne vereceğini almaya karar vermeden önce böyle incelersiniz.
Boş stack istisnası ve TryPop
Boş bir stack'te pop ya da peek yapmak InvalidOperationException fırlatır. Bu en çok, kapanış öğeleri açılışlardan fazla olan girdiyle beslenen parser'larda ve algoritmalarda ortaya çıkar.
Çıktı:
Caught InvalidOperationException
True 10
False 0
TryPop ve TryPeek (.NET Core 2.0 ve sonrası) boş bir stack'te false döndürür ve out değişkenini varsayılan değere, burada 0'a ayarlar. .NET Framework'te önce Count > 0 kontrol edin.
Dolaşma sırası: önce en üst
Bir stack'i dolaşmak hiçbir şeyi çıkarmaz ve Pop'un öğeleri döndüreceği sırayla, yukarıdan aşağıya gider:
Çıktı:
checkout products home
checkout > products > home
True
home
checkout
Ters çevrilmiş kopya insanları yakalar: constructor herhangi bir IEnumerable<T> alır ve öğelerini sırayla push eder, stack de önce en üstten dolaşılır, bu yüzden eski en üst kopyanın en altına düşer. Önce diziyi ters çevirmek (LINQ'in Reverse()'ü öğeleri alttan başlayarak döndürür) aynı üste sahip bir kopya verir.
Bir öğe listesini yeni bir stack'e push etmek de onları ters çevirir; bu, bir diziyi ters çevirmenin hızlı bir yoludur: new Stack<char>("hello") geriye o, l, l, e, h olarak pop edilir.
Örnek: bir geri alma geçmişi
Editörler her değişikliği bir stack'te tutar. Geri alma en son değişikliği pop edip geri çevirir; yineleme ise geri alınan değişikliklerden oluşan ikinci bir stack tutar.
Çıktı:
Hello, world!
Hello, world
Hello
Hello, world
Tüm anlık görüntüleri saklamak en basit sürümdür. Gerçek editörler bunun yerine, her biri kendini geri çevirecek bir metoda sahip küçük komut nesneleri (ne eklendi ve nereye) push eder, ama iki stack aynı şekilde çalışır.
Örnek: dengeli parantezler
(, [ ve {'nin doğru sırayla kapatıldığını kontrol etmek standart stack alıştırmasıdır ve aynı mantık her derleyicinin ve JSON parser'ının içinde bulunur.
Çıktı:
"f(a[i], {x: 1})" -> True
"(]" -> False
"((a)" -> False
"a)b(" -> False
"" -> True
Üç başarısızlık kontrolü, parantezlerin bozulabileceği üç yola karşılık gelir: açık hiçbir şey yokken bir kapanış (a)b(, Pop'tan gelen bir istisna yerine Count == 0 ile yakalanır), yanlış türde bir kapanış ((]) ve hiç kapatılmamış açılışlar (((a), son kontrolle yakalanır).
Diğer kullanımlar
- Derinlik öncelikli arama. Genişlik öncelikli bir aramadaki kuyruğu bir stack ile değiştirin, dolaşma genişlemeden önce derine gider. Açık bir stack, girdi yakalanamayan bir
StackOverflowExceptionriskine yetecek kadar derin olduğunda özyinelemenin yerini de alır. - İfadeleri değerlendirmek. Sonek gösterim (
3 4 + 2 *), sayıları push edip her operatör için iki tane pop ederek değerlendirilir. - Geri izleme. Gezinme geçmişi, labirent çözme ve parser durumları bir konumu push eder ve çıkmaza girildiğinde ona geri pop eder.
İlk giren ilk çıkar karşılığı için Queue sayfasına bakın.
Stack, Queue ve List
Stack<T> | Queue<T> | List<T> | |
|---|---|---|---|
| Çıkış sırası | Önce en yeni | Önce en eski | Herhangi, indeksle |
| Eklemek | Push | Enqueue | Add, Insert |
| Çıkarmak | Pop (üst) | Dequeue (ön) | Remove, RemoveAt |
| Bakmak | Peek | Peek | list[i] |
| Güvenli varyantlar | TryPop, TryPeek | TryDequeue, TryPeek | gerekmez |
Birkaç thread için System.Collections.Concurrent içindeki ConcurrentStack<T> lock olmadan Push, TryPop ve TryPeek sunar.
Yaygın hatalar
- Kontrol etmeden Pop yapmak. Boş bir stack
InvalidOperationExceptionfırlatır;Count'u kontrol edin ya daTryPopkullanın. foreach'in ilk push edilen öğeden başlamasını beklemek. En üstten başlar.new Stack<T>(stack)ile kopyalamak. Kopya ters çevrilmiştir.- Aynı stack üzerindeki
foreachiçinde Push yapmak. İstisna fırlatır; birwhile (stack.Count > 0)döngüsü kullanın.
Sıkça Sorulan Sorular
C#'ta Stack nedir?
System.Collections.Generic içindeki Stack<T>, son giren ilk çıkar (LIFO) bir koleksiyondur. Push en üste bir öğe koyar, Pop en üstteki öğeyi çıkarıp döndürür ve Peek en üstteki öğeyi çıkarmadan döndürür. Üçü de sabit zamanda çalışır.
C#'ta boş bir stack'te Pop yapınca ne olur?
Stack boşken Pop ve Peek InvalidOperationException fırlatır. Önce stack.Count > 0 kontrol edin ya da istisna fırlatmak yerine false döndüren TryPop(out var item) ve TryPeek(out var item)'i kullanın (.NET Core 2.0 ve sonrası).
foreach bir Stack'i hangi sırayla dolaşır?
Yukarıdan aşağıya: en son eklenen öğe önce gelir; Pop'un onları döndüreceği sırayla aynı. ToArray() de aynı sırayı kullanır. Bunun bir sonucu, new Stack<T>(otherStack)'in ters çevrilmiş bir kopya üretmesidir, çünkü constructor öğeleri dolaştığı sırayla push eder.
C#'ta Stack ile Queue arasındaki fark nedir?
Bir Stack<T> önce en yeni öğeyi döndürür (son giren ilk çıkar), bir Queue<T> ise önce en eski öğeyi döndürür (ilk giren ilk çıkar). Geri alma geçmişi, iç içe yapılar ve derinlik öncelikli arama için stack; işi geliş sırasıyla işlemek ve genişlik öncelikli arama için queue kullanın.
C#'ta dengeli parantezler nasıl kontrol edilir?
String'i bir kez tarayın. Her açılış parantezini bir Stack<char>'a push edin. Her kapanış parantezi için stack boş olmamalı ve en üstü eşleşen açılış parantezi olmalıdır; sonra onu pop edersiniz. Tarama stack boşken biterse string dengelidir.