Sırala (C ++) - Sort (C++)

çeşit bir genel işlevi C ++ Standart Kitaplık yapmak için karşılaştırmalı sıralama. İşlev, Standart Şablon Kitaplığı (STL).

Spesifik sıralama algoritması dil standardı tarafından zorunlu tutulmaz ve uygulamalar arasında değişiklik gösterebilir, ancak En kötü durumda asimptotik işlevin karmaşıklığı belirtilir: bir çağrı çeşit gerçekleştirmeli Ö(N günlük N) bir dizi uygulandığında karşılaştırmalar N elementler.[1]

Kullanım

çeşit işlevi, <algorithm> C ++ Standart Kitaplığı'nın başlığı ve üç argümanlar: Önce RandomAccessIterator, son olarak RandomAccessIterator, Karşılaştırma comp. Buraya, RandomAccessIterator bir şablonlu olması gereken tip rastgele erişim yineleyici, ve ilk ve son bir değer dizisi tanımlamalıdır, yani son şuradan ulaşılabilir olmalı ilk tekrar tekrar uygulayarak artırma operatörü -e ilk. Yine şablonlu tipte olan üçüncü argüman, bir karşılaştırma yüklemini belirtir. Bu karşılaştırma koşulu, bir sıkı zayıf sipariş sıralanacak dizinin öğeleri üzerinde. Üçüncü argüman isteğe bağlıdır; belirtilmezse, "küçüktür" (<) operatör kullanılır; aşırı yüklenmiş C ++ 'da.

Bu kod örneği, belirli bir tamsayı dizisini sıralar (artan sırada) ve yazdırır. Dizideki işaretçiler yineleyici işlevi görür.

#Dahil etmek <algorithm>#Dahil etmek <iostream>kullanma ad alanı std;int ana() {  int dizi[] = { 23, 5, -10, 0, 0, 321, 1, 2, 99, 30 };  size_t boyut = boyutu(dizi) / boyutu(dizi[0]);   çeşit(dizi, dizi + boyut);  için (size_t ben = 0; ben < boyut; ++ben) {     cout << dizi[ben] << ' ';  }  cout << son;}

Aynı işlevsellik bir vektör konteyner, kullanma başla ve son yineleyiciler elde etme yöntemleri:

#Dahil etmek <algorithm>#Dahil etmek <iostream>#Dahil etmek <vector>kullanma ad alanı std;int ana() {  vektör<int> vec { 23, 5, -10, 0, 0, 321, 1, 2, 99, 30 };  çeşit(vec.başla(), vec.son());  için (int ben = 0; ben < vec.boyut(); ++ben) {     cout << vec[ben] << ' ';  }  cout << son;}

Genellik

çeşit genel olarak belirtilir, böylece herhangi bir rasgele erişim konteyner ve bir unsur olduğunu belirlemenin herhangi bir yolu x böyle bir kabın başka bir elemanın önüne yerleştirilmesi gerekir y.

Genel olarak belirtilmesine rağmen, çeşit kolayca uygulanmaz herşey sıralama sorunları. Bazı araştırmaların konusu olan belirli bir sorun şudur:

  • İzin Vermek Bir ve B eleman arasında bir ilişki olduğu iki dizi olabilir A [i] ve eleman B [i] tüm geçerli endeksler için ben.
  • Çeşit Bir ile ilişkiyi sürdürürken Byani aynısını uygulayın permütasyon -e B bu sıralar Bir.
  • Bir öncekini, öğelerini kopyalamadan yapın Bir ve B yeni bir diziye çiftler, sıralama ve öğeleri orijinal dizilere geri taşıma ( Ö(n) geçici alan).

Bu soruna bir çözüm, dizi çiftleri için özel bir yineleyici türü uygulayan ve böyle bir yineleyici türünün doğru şekilde uygulanmasındaki bazı zorlukları analiz eden A. Williams tarafından 2002'de önerildi.[2] Williams'ın çözümü K. Åhlander tarafından incelendi ve geliştirildi.[3]

Karmaşıklık ve uygulamalar

C ++ standardı, çeşit performans Ö(N günlük N) bir dizi uygulandığında karşılaştırmalar N elementler.[4]C ++ 'ın önceki sürümlerinde, örneğin C ++ 03, yalnızca ortalama karmaşıklık gerekliydi Ö(N günlük N).[5] Bu, (medyan-of-3) gibi algoritmaların kullanımına izin vermekti. hızlı sıralama, ortalama durumda hızlıdır, gerçekten de diğer algoritmalardan çok daha hızlıdır. yığın sıralama optimal en kötü durum karmaşıklığı ile ve en kötü durum ikinci dereceden karmaşıklığın nadiren meydana geldiği durumlarda.[6] Tanımı hibrit algoritmalar gibi tanıtım hem hızlı ortalama performansa hem de optimum en kötü durum performansına izin verdi ve böylece karmaşıklık gereksinimleri sonraki standartlarda sıkılaştırıldı.

Farklı uygulamalar farklı algoritmalar kullanır. GNU Standard C ++ kitaplığı örneğin, 3 parçalı bir karma sıralama algoritması kullanır: tanıtım ilk olarak gerçekleştirilir (introsort, hızlı sıralama ve yığın sıralamanın bir melezidir), 2 × log ile verilen maksimum derinliğe2 n, nerede n elemanların sayısıdır, ardından bir ekleme sıralaması sonuçta.[7]

Diğer sıralama türleri

çeşit kararlı değildir: sıralamadan bir yol önce sıralanan eşdeğer öğeler, sıralamadan sonra farklı şekilde sıralanabilir. stabil_sort daha kötü performans pahasına (bazı durumlarda) sonucun istikrarını sağlar, yalnızca yarı doğrusal zaman üslü 2 - O (n günlük2 n) - ek bellek yoksa, ancak linearitmik zaman Ö(n günlük n) ek bellek varsa.[8] Bu, kullanımına izin verir yerinde birleştirme sıralaması yerinde kararlı sıralama ve ek bellekle kararlı sıralama için düzenli birleştirme sıralaması için.

Kısmi sıralama tarafından uygulanıyor kısmi_sıralamabir dizi alan n elemanlar ve bir tam sayı m < nve aralığı yeniden sıralar, böylece en küçük m öğeler ilk sırada m sıralı sırayla pozisyonlar (kalan nm kalan pozisyonlarda, bazı belirtilmemiş sırayla). Tasarıma bağlı olarak bu, tam ayırmadan çok daha hızlı olabilir. Tarihsel olarak, bu genellikle bir yığın alan tabanlı algoritma Θ (n + m günlük n) en kötü durum zamanı. Daha iyi bir algoritma denen Quickselsort Kopenhag STL uygulamasında kullanılır ve karmaşıklığı Θ (n + m günlük m).[9]

Seçimi of ninci öğe tarafından uygulanır nth_element, aslında yerinde kısmi sıralamayı uygulayan: nAyrıca, bu elemanın, kendisinden önceki elemanların kendisinden küçük ve ondan sonraki elemanların ondan büyük olmasını sağlar. Bunun ortalama olarak doğrusal zaman alması şartı vardır, ancak en kötü durum şartı yoktur; bu gereksinimler tam olarak karşılanır hızlı seçim, herhangi bir pivot strateji seçimi için.

Aralarında bazı kaplar liste, özel sürümünü sağlayın çeşit üye işlevi olarak. Bunun nedeni, bağlantılı listelerin rastgele erişime sahip olmamasıdır (ve bu nedenle normal çeşit işlevi); ve özelleştirilmiş sürüm de yineleyicilerin işaret ettiği değerleri korur.

Qsort ile karşılaştırma

Den başka çeşit, C ++ standart kitaplığı ayrıca qsort işlevinden C standart kitaplığı. Nazaran qsort, şablonlu çeşit güvenli olmayan yollarla veri öğelerine erişim gerektirmediğinden daha tür güvenlidir geçersiz işaretçiler olarak qsort yapar. Ayrıca, qsort Karşılaştırma işlevine bir işlev işaretçisi kullanarak erişir, çok sayıda tekrarlanan işlev çağrısı gerektirir, oysa çeşitkarşılaştırma işlevleri olabilir satır içi bir şablon somutlaştırması için oluşturulan özel nesne koduna. Uygulamada, C ++ kodu kullanılarak çeşit tamsayılar gibi basit verileri sıralamak için eşdeğer C kodundan çok daha hızlıdır. qsort.[10]

Referanslar

  1. ^ "Çalışma Taslağı, Programlama Dili için Standart C ++" (PDF). ISO. s. 911.
  2. ^ Williams, Anthony (2002). "Yineleyicilerle eşleştirme" (PDF). Sadece Yazılım Çözümleri.
  3. ^ Åhlander, Krister (2005). Yineleyici Çiftleri, Değerler ve Referanslar Arasındaki İlişkileri Ayırma. Proc. Uluslararası Konf. Üretken Programlama: Kavramlar ve Deneyimler. LNCS. 3676. sayfa 342–356. CiteSeerX  10.1.1.184.8947.
  4. ^ "Çalışma Taslağı, Programlama Dili için Standart C ++" (PDF). ISO. s. 911.
  5. ^ ISO /IEC (2003). ISO / IEC 14882: 2003 (E): Programlama Dilleri - C ++ §25.3.1.1 sıralama [lib.sort] para. 2
  6. ^ "Genel Algoritmalar ", David Musser
  7. ^ libstdc ++ Belgeler: Sıralama Algoritması
  8. ^ stabil_sort
  9. ^ Martínez, Conrado (2004). Kısmi hızlı sıralama (PDF). Proc. 6. Algoritma Mühendisliği ve Deneyleri üzerine ACM-SIAM Çalıştayı ve Analitik Algoritmalar ve Kombinatorikler üzerine 1. ACM-SIAM Çalıştayı.
  10. ^ Meyers, Scott (2001). Etkili STL: Standart şablon kitaplığı kullanımınızı iyileştirmenin 50 özel yolu. Addison-Wesley. s. 203. ISBN  0-201-74962-9. Alıntıda boş bilinmeyen parametre var: | ortak yazarlar = (Yardım)

Dış bağlantılar