Birleştirme türündeki “bölme” adımından kaçınılabilir mi?


13

Sıralamayı birleştir

Yani birleştirme sıralama bir böl ve fethet algoritmasıdır. Yukarıdaki şemaya bakarken, tüm bölünme adımlarını atlamanın mümkün olup olmadığını düşünüyordum.

İki adım atlayarak orijinal dizi üzerinde yinelediyseniz, öğeleri i ve i + 1 dizininde alabilir ve bunları kendi sıralı dizilerine koyabilirsiniz. Tüm bu alt dizileri (şemada gösterildiği gibi [7,14], [3,12], [9,11] ve [2,6]) elde ettikten sonra, almak için normal birleştirme rutini ile devam edebilirsiniz. sıralı bir dizi.

Dizi üzerinden yineleme yapmak ve gerekli alt dizileri derhal oluşturmak, bölme adımlarını bütünüyle gerçekleştirmekten daha az verimli mi?


Yanıtlar:


29

Karışıklık , algoritmanın kavramsal tanımı ile uygulanması arasındaki farktan kaynaklanmaktadır .

Mantıksal olarak birleştirme sıralaması diziyi daha küçük dizilere bölmek ve sonra bunları tekrar birleştirmek olarak tanımlanır. Bununla birlikte, "dizinin bölünmesi", "bellekte tamamen yeni bir dizi oluşturulması" veya bunun gibi bir şey anlamına gelmez - kodda şu şekilde uygulanabilir:

/*
 * Note: array is now split into  [0..n) and [n..N)
 */

yani gerçek bir çalışma yapılmaz ve "bölme" tamamen kavramsaldır. Öyleyse önerdiğiniz şey kesinlikle işe yarıyor, ama mantıksal olarak dizileri hala "bölüyorsunuz" - bunu yapmak için bilgisayardan herhangi bir çalışmaya ihtiyacınız yok :-)


4
Şahsen ben aşağıdan yukarıya birleştirme sıralama gerçekten seviyorum çünkü her özyineleme düzeyinde bir geçici arabellek ayırmaktan kaçınmanızı sağlayacak şekilde uygulamak daha kolaydır. Bunun yerine bir kez bir tampon ve aralarında pinpon ayırırsınız.
cırcır ucube

Bu - bölünme hesaplama açısından bir işlem yapmaz ... artı OPs önerisi, tek eleman dizilerinin birleşmesine eşdeğer bir giriştir ve 2. adımdan birleştirme kullanmaya başlayarak gereksizdir, çünkü orijinal birleştirme de aynı şekilde çalışır. Bunu optimize etmenin bir anlamı yok. Sadece gereksiz kavramlar ve mantık getirir.
luk32

@ratchetfreak: Ben de seviyorum, ama ne yazık ki yukarıdan aşağıya eşdeğer değil (en azından bildiğim sürüm). Farklı birleştirme yapacağız, temelde bir sonraki 2 güç dizisine kadar yuvarlanıyor, ki bu biraz daha yavaş bile olabilir. Başka bir yerde ağır bir ücret ödemeden aynı birleştirme yapan aşağıdan yukarıya bir versiyon biliyor musunuz?
user541686

@Mehrdad'ın tek gerçek sorunu, birleştirilmesi gereken küçük kuyruktur. En kötü durumda, uzunluk dizileri için tek bir öğede birleşmek için başka bir geçiş anlamına gelir 1<<n+1. Herşeyi ayarlayabileceğinize rağmen, çok küçük bir kuyruk daha düşük bir geçişte birleşir.
cırcır ucube

@psmears "sadece bunu yapmak için bilgisayardan herhangi bir çalışma gerekmez" - bu yüzden bazı özyinelemeli bölme işlevinin n çağrılarının performans maliyetini tahmin ediyorum (örnek şemada 7 çağrı) temelde ihmal edilebilir mi?
Jimmy_Rustle

11

Ne demek istediğini aşağıdan yukarıya uygulama . Aşağıdan yukarıya uygulamada, tek hücre öğelerinden öğeleri daha büyük sıralı listelere / dizilere birleştirerek yukarı doğru bir harekete başlarsınız. Yukarıdaki şekilde orta diziden başlayarak, yani tek elemanlı dizilerden başlayarak okları ters çevirmeniz yeterlidir.

Ayrıca, dizileri sabit bir boyuta ulaşana kadar bölerek birleştirme sıralamasını optimize etmek isteyebilirsiniz , daha sonra bunları örneğin ekleme sıralama kullanarak sıralayabilirsiniz.

Aksi takdirde, diziyi bölmeden sıralama mümkün değildir. Aslında Birleştirme sıralamasının özü, alt dizileri bölmek ve sıralamak, yani böl ve fethetmektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.