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