Hâlâ birleşip sıralayamadığını duydum?

Yazar | Chaoyue Life

Baş Editör | Guo Rui

Bu makale, birleştirme sıralamanın temel fikrini, özyinelemeli yöntemin genel yazımını ve son olarak, adım adım elle yazma birleştirme sıralamayı tanıtmakta ve performansını analiz etmektedir.

Temel fikir

Birleştirme sıralaması, birleştirme işlemine dayanan etkili bir sıralama algoritmasıdır.Bu algoritma, çok tipik bir bölme ve yönetme uygulamasıdır. Yani, önce her bir alt diziyi sıralı hale getirin ve ardından tamamen sıralı bir sıra elde etmek için mevcut sıralı alt dizileri birleştirin. İşte birleştirme sıralamanın yinelemeli bir uygulaması.

Özyinelemeli yöntemin genel yazımı

Özyinelemeli bir yöntem yazmanın üç ana adımı vardır:

  • Özyinelemeli yöntemlerin işlevsel sınırlarını netleştirin;

  • Özyinelemeli özyineleme ilişkisini alın;

  • Özyinelemenin sonlandırma koşulu göz önüne alındığında.

Özyinelemeli yöntemler, bu üç adıma uygun olarak gerçekleştirilebilir ve özyinelemeli uygulamanın ayrıntılarına girmez. Özyinelemeli yöntemin özel yazımı hakkında konuşmak için birleştirme sıralama algoritmasının yazımını örnek olarak alalım.

El yazısı birleştirme sıralaması

İlk olarak, özyinelemeli yöntemin işlevini açıklığa kavuşturun.Burada yöntemin işlevini, bir dizi ve sol ve sağ sınırlar verildiğinde, yöntem, aşağıdaki gibi dizi sınırları içindeki öğelerin sıralanmasını tamamladığı şekilde tanımlarız:

özel statik void mergeSort (int arr, int left, int right);

Özel uygulamadan bağımsız olarak böyle bir yönteme zaten sahip olduğumuzu varsayalım.

Sonra, bir yineleme ilişkisi arayın. Yineleme ilişkisi nedir? Alt problemin çözümünden orijinal problemin çözümü nasıl alınır veya örneğin aşağıdaki diziler vardır:

Orijinal dizi

Aşağıdaki gibi iki bölüme ayırıyoruz:

Bölünmüş dizi

Yineleme ilişkisi, eğer sol ve sağ kısımlar zaten sıralıysa, dizinin tamamı nasıl sırayla yapılır? Bu soruya aslında bir dizi verilir, dizinin sol yarısı sıralı, sağ yarısı da sıralıdır.Tüm dizi nasıl sırayla yapılır?

İlk olarak, sırasıyla sol bölümün başlangıç konumunu ve sağ bölümün başlangıç konumunu işaret etmek için iki işaretçi tanımlayın ve bir yardımcı dizi ve başlangıç konumuna işaret eden yardımcı işaretçiler oluşturun:

İşaretçi ve yardımcı diziyi tanımlayın

Ardından, sol işaretçiye ve sağ işaretçiye karşılık gelen öğelerin boyutunu karşılaştırın, daha küçük öğe yardımcı diziye doldurulur ve karşılık gelen işaretçi ve yardımcı işaretçi aşağıdaki gibi 1 artar:

Yardımcı diziyi karşılaştırın ve doldurun

Sol işaretçi orta konumu işaret edene veya sağ işaretçi dizinin sonunu gösterene kadar sırayla devam edin.Bu sırada, kalan elemanlar yardımcı diziye doldurulur. Tüm öğeler doldurulduktan sonra, yardımcı dizideki öğeleri orijinal diziye geri doldurun. Spesifik kod aşağıdaki gibidir:

/ ** * * @param arr Birleştirilecek dizi * @param sol sol sınır * @param orta orta sınır * @param sağ sağ sınır * / özel statik boşluk birleştirme (int arr, int left, int mid, int sağ) {int helpArr = new int; // İlk önce bir yardımcı dizi tanımlayın int lPoint = left; // sol işaretçi int rPoint = mid + 1; // sağ işaretçi int i = 0; // yardımcı işaretçi while (nokta < = orta rPoint < = sağ) {// yardımcı diziyi karşılaştırın ve doldurun if (dizi < = arr) helpArr = arr; else helpArr = arr;} while (nokta < = mid) {// kalan öğeleri yardımcı diziye doldurun helpArr = arr;} while (rPoint < = sağ) {helpArr = dizi;} for (int j = 0; j < helpArr.length; j ++) {// Yardımcı dizideki öğeleri orijinal diziye doldurun arr = helpArr;}}

Son olarak, sonlandırma koşulunu belirleyin, genellikle dizi boştur veya dizide yalnızca bir öğe vardır, sadece dönün.

Artık birleştirme sıralama kodunun tamamını aşağıdaki gibi yazabiliriz:

private static void mergeSort (int arr, int left, int right) {if (arr == || right == left) // sonlandırma koşulu dönüşü; int mid = left + (sağ-sol) / 2; // bölmeyi belirle MergeSort (arr, left, mid); // MergeSort (arr, mid + 1, right) sıralı hale getirmek için sol yarıdaki özyinelemeli yöntemi çağırın; // Sıralamak için sağ yarıdaki özyinelemeli yöntemi çağırın birleştirme (dizi, sol, orta, sağ); // Tüm diziyi sırayla yapmak için sol ve sağ parçaları birleştir}

Formun bütünlüğünü sağlamak için fonksiyon tekrar kapsüllenir, aşağıdaki gibi bu bizim birleştirme sıralamamızdır.

/ ** * Birleştirme sıralama algoritması * @param arr * / public static void mergeSort (int arr) {mergeSort (arr, 0, arr.length-1); // Yazılı yinelemeli birleştirme sıralama yöntemini çağırın}

Bu noktada, birleştirme sıralama algoritmasının kod uygulamasını tamamladık.

Performans analizi

Birleştirme sıralama algoritmasının performansını analiz etmeden önce, birkaç temel kavram tanıtıldı.

  • Zaman karmaşıklığı: bir algoritmanın yürütmek için harcadığı zaman;

  • Alan karmaşıklığı: bir algoritma çalıştırmak için gereken bellek miktarı;

  • Yerinde sıralama: Sıralama işlemi sırasında fazladan depolama alanı için başvurmayın ve karşılaştırma ve veri sıralama alışverişi için sıralanacak veriler için yalnızca orijinal depolama alanını kullanın.

  • Yerinde olmayan sıralama: Sıralamaya yardımcı olmak için ek diziler kullanmanız gerekir.

  • Kararlı sıralama: Eğer a başlangıçta b'nin önündeyse ve a == b, sıraladıktan sonra a hala b'nin önündeyse, kararlı bir sıralamadır.

  • Kararsız sıralama: Eğer a başlangıçta b'nin önündeyse ve a == b, sıralamadan sonra a, b'nin önünde olmayabilir, kararsız bir sıralamadır.

Aşağıda birleştirme sıralama algoritmasının performansını analiz ediyoruz.

Birincisi, zaman karmaşıklığıdır. Birleştirme sıralama algoritması, sıralama sırasında önce sorunu ayrıştırır, ardından alt problemleri çözer ve sonra birleştirir, böylece toplam süre = ayrıştırma süresi + alt problem çözme süresi + birleştirme süresi. Ayrıştırma süresi, bir diziyi iki parçaya ayırmaktır, zaman bir sabittir, yani O (1); alt problemi çözme süresi iki özyinelemeli yöntemdir ve bir ölçek problemi, iki n / 2 ölçeğine bölünür. Alt problem için zaman 2T (n / 2); birleştirme zamanı karmaşıklığı O (n). Yani toplam süre T (n) = 2T (n / 2) + O (n). Bu yinelemeli problemin zaman karmaşıklığı aşağıdaki formül ile hesaplanabilir

Özyinelemeli fonksiyonun zaman karmaşıklığı hesaplama formülü

Bu formül, aşağıdaki formdaki özyinelemeli bir denklemin zaman karmaşıklığını çözebilir: T (n) = aT (n / b) + f (n). Birleştirme sıralamanın zaman karmaşıklığının O (nlogn) olduğu görülebilir. Ek olarak, birleştirme sıralamanın zaman karmaşıklığı en kötü, en iyi ve ortalama durumlarda O (nlogn) olur.

  • Uzay karmaşıklığı analizi: Sıralama sürecinde, orijinal diziyle aynı uzunlukta bir yardımcı dizi kullanılır ve uzay karmaşıklığının O (n) olduğu tahmin edilir.

  • Kararlılık analizi: Birleştirme sıralamanın kararlı bir tür olduğu, ayırma sürecinden anlaşılabilir.

  • Yerinde sıralamanın yapılıp yapılmayacağı: yardımcı dizi sıralama işleminde kullanılır, bu nedenle yerinde dizilir.

Bu makalenin kaynak kodu github ile senkronize edilmiştir, adres: https://github.com/zhanglianchao/AllForJava/tree/master/src/algorithm/sort.

Feragatname: Bu makale yazar tarafından sunulmuştur ve telif hakkı kendisine aittir.

Zen'e gidin

Luhan'ın yapay zeka hayranları var, yapay zeka yüz değiştiren dramanın etkisi neden bu kadar aptalca?

Döngüsel Zeka Yang Zhilin: "İnsan-makine bağlantısı" diyalog semantik uygulamalarında yeni bir trend olacak!

Zhou Hongyi tarafından tüm ağdan yasaklanan 360 asil general: tabandan 36 yaşına kadar olan ve net değeri yüz milyonlarca olan bir karşı saldırı!

Kubernetes'in uç bilişim alanında ayrıntılı gelişimi

Salgından sonra, küresel kripto topluluğunun koronavirüsle savaşmak için çok şey yaptığı ortaya çıktı!

Perakendecilikte "duygusal bilgi işlemin" uygulamasını ve gelişimini anlamak için bir makale

Lütfen bana yığının ne olduğunu sorma
önceki
PPT, PyeCharts kadar havalı nasıl yapılır?
Sonraki
Kıdemli bir geliştirici gibi nasıl düşünülür?
Bilmediğin LVS sırları
Tek noktadan katil yapay zeka geliştirme platformu burada! Parçalı modelleme araçlarını değiştirmeye elveda deyin
Google Wave'in başarısızlığı, modern gerçek zamanlı ortak çalışma ofisine büyük bir ders veriyor
Üç büyük operatör 5G haberlerini başlatacak; Apple ve Google ekibi 3 milyar kullanıcıyı takip edecek; jQuery 3.5.0 yayınlandı | Geek Headlines
Derinlik | Perakendede "duygusal bilgi işlem" in uygulama geliştirmesini tek bir makalede okuyun
Yeni bir programcı iş ararken nasıl özgeçmiş yazmalıdır?
Zen of Go
10 satırlık Python kodu hangi ileri teknoloji işlemlere sahip olabilir? | Güç Projesi
Muhabir: Birkaç röportaj sorusunu ezberledikten sonra, Java kaynak koduna aşina olduğunuzu söylemeye cesaret edebilir misiniz? Kaynak kodunu bile bilmeyen kişileri işe almıyoruz Güç Projesi
400 satırdan fazla kod! Süper ayrıntılı Rasa Çince sohbet robotu geliştirme kılavuzu | Kuvvet Projesi
Luhan'ın AI hayranları var, AI'nın yüz değiştiren dramasının etkisi neden bu kadar aptalca?
To Top