Susun Shell di Jawa

1. Pengenalan

Dalam tutorial ini, kita akan menerangkan algoritma semacam Shell di Java.

2. Gambaran Keseluruhan Shell Shell

2.1. Penerangan

Mari kita jelaskan algoritma semacam Shell supaya kita tahu apa yang cuba kita laksanakan.

Penyortiran shell berdasarkan algoritma penyortiran Penyisipan, dan ia tergolong dalam kumpulan algoritma yang sangat cekap. Secara umum, algoritma memecah set asal menjadi subset yang lebih kecil dan kemudian masing-masing disusun menggunakan jenis Insertion .

Tetapi, bagaimana ia membuat subset tidak mudah. Ia tidak memilih elemen jiran untuk membentuk subset seperti yang kita jangkakan. Sebaliknya, jenis shell menggunakan selang atau jurang yang disebut untuk pembuatan subset. Sebagai contoh, jika kita mempunyai jurang I , ini bermaksud bahawa satu subset akan mengandungi unsur-unsur yang terpisah dari kedudukan I.

Pertama, algoritma menyusun elemen yang berada jauh antara satu sama lain. Kemudian, jurang menjadi lebih kecil dan elemen yang lebih dekat dibandingkan. Dengan cara ini, beberapa elemen yang tidak berada dalam posisi yang betul dapat diposisikan lebih cepat daripada jika kita membuat subset dari elemen tetangga.

2.2. Satu contoh

Mari kita lihat ini dalam contoh dengan jurang 3 dan 1 dan senarai 9 elemen yang tidak disusun:

Sekiranya kita mengikuti penerangan di atas, pada lelaran pertama, kita akan mempunyai tiga subset dengan 3 elemen (diserlahkan dengan warna yang sama):

Setelah menyusun setiap subset pada lelaran pertama, senarai akan kelihatan seperti:

Kita dapat perhatikan bahawa, walaupun kita belum mempunyai senarai yang disusun, elemen-elemennya sekarang lebih dekat dengan posisi yang diinginkan.

Akhirnya, kita perlu melakukan satu lagi jenis dengan kenaikan satu dan itu sebenarnya jenis penyisipan asas. Jumlah operasi peralihan yang perlu kita lakukan untuk menyusun senarai sekarang lebih kecil daripada yang akan terjadi sekiranya kita tidak melakukan lelaran pertama:

2.3. Memilih Jujukan Jurang

Seperti yang telah kami sebutkan, jenis shell mempunyai cara yang unik untuk memilih urutan jurang. Ini adalah tugas yang sukar dan kita harus berhati-hati untuk tidak memilih jurang yang terlalu sedikit atau terlalu banyak. Maklumat lebih lanjut boleh didapati dalam senarai urutan jurang yang paling dicadangkan.

3. Pelaksanaan

Sekarang mari kita lihat pelaksanaannya. Kami akan menggunakan urutan asal Shell untuk kenaikan selang:

N/2, N/4, …, 1 (continuously dividing by 2)

Pelaksanaannya sendiri tidak terlalu rumit:

public void sort(int arrayToSort[]) { int n = arrayToSort.length; for (int gap = n / 2; gap > 0; gap /= 2) { for (int i = gap; i = gap && arrayToSort[j - gap] > key) { arrayToSort[j] = arrayToSort[j - gap]; j -= gap; } arrayToSort[j] = key; } } }

Kami mula-mula membuat urutan jurang dengan gelung untuk dan kemudian melakukan penyisipan untuk setiap ukuran jurang.

Sekarang, kita boleh menguji kaedah kita dengan mudah:

@Test public void givenUnsortedArray_whenShellSort_thenSortedAsc() { int[] input = {41, 15, 82, 5, 65, 19, 32, 43, 8}; ShellSort.sort(input); int[] expected = {5, 8, 15, 19, 32, 41, 43, 65, 82}; assertArrayEquals("the two arrays are not equal", expected, input); }

4. Kerumitan

Secara umumnya, algoritma semacam Shell sangat efisien dengan senarai bersaiz sederhana . Kerumitan sukar ditentukan kerana banyak bergantung pada urutan jurang, tetapi kerumitan masa berbeza antara O (N) dan O (N ^ 2) .

Kerumitan ruang terburuk adalah O (N) dengan ruang tambahan O (1) .

5. Kesimpulan

Dalam tutorial ini, kami menerangkan jenis Shell dan menggambarkan bagaimana kami dapat menerapkannya di Java.

Seperti biasa, keseluruhan kod boleh didapati di GitHub.