Jenis Cepat Normal
Temukan basis nilai dasar, dan kemudian urutkan dalam satu perjalanan sehingga angka -angka di sebelah kiri pangkalan lebih kecil dari pangkalan, dan angka -angka di sebelah kanan pangkalan lebih besar dari atau sama dengan basis. Kemudian bagilah menjadi dua penyortiran subarray. Rekursif seperti ini.
Public Class quicksort {public static <t memperluas sebanding <? super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1);} public static <t extends sebanding <? super t >> void sort (t [] arr, int kiri, int kanan) {if (kiri> = kanan) kembali; int p = partisi (arr, kiri, kanan); sort (arr, kiri, p - 1); urutkan (arr, p + 1, kanan);} private static <t memperpanjang sebanding <? super T>> int partition(T[] arr, int left, int right) {T base = arr[left];int j = left;for (int i = left + 1; i <= right; i++) {if (base.compareTo(arr[i]) > 0) {j++;swap(arr, j, i);}}swap(arr, left, j);return j;//Return the lower corner of the base value after lying penyortiran} public static void swap (objek [] arr, int i, int j) {if (i! = j) {objek temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private static printarr (objek [] arr) {untuk (objek o: arr) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Optimalisasi Sortir Cepat: Pilih Basis Nilai Basis Secara Acak
Ketika array hampir dipesan, kinerja pesanan cepat buruk (karena setelah setiap pesanan, ukuran rekursif dari subs kiri dan kanan sangat berbeda, dan bagian yang lebih besar cenderung mencapai O (n^2) pada akhirnya).
Solusi: Nilai referensi dipilih secara acak, daripada mengambil angka pertama setiap saat. Ini tidak akan terganggu oleh "array yang hampir dipesan". Tetapi kinerja penyortiran "array yang hampir tidak sesuai pesanan" dapat turun sedikit, setidaknya ada lebih banyak bagian yang ditukar sebelum disortir. Pertukaran ini tidak ada artinya di luar orde ... ada banyak komponen "keberuntungan" ...
Public Class quicksort {public static <t memperluas sebanding <? super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1);} public static <t extends sebanding <? super t >> void sort (t [] arr, int kiri, int kanan) {if (kiri> = kanan) kembali; int p = partisi (arr, kiri, kanan); sort (arr, kiri, p - 1); urutkan (arr, p + 1, kanan);} private static <t memperpanjang sebanding <? super t >> int partisi (t [] arr, int kiri, int kanan) {// sebelum menyortir, biarkan nilai referensi dipertukarkan dengan nomor acak. Dengan cara ini, nilai referensi acak. // Ini tidak akan menyebabkan skala rekursif dari sisi kiri dan kanan tidak konsisten ketika array relatif dipesan, menghasilkan swap kompleksitas waktu terburuk (ARR, kiri, (int) (math.random ()*(kanan - kiri+1)+kiri)); t basis = ARR [kiri]; int j = kiri; untuk (int i = 1) kiri)); t basis = ARR [kiri]; int j = kiri; untuk (int i = 1) kiri)); t basis = ARR [kiri]; int j = for (int i = kiri+1; > 0) {j ++; swap (arr, j, i);}} swap (arr, kiri, j); return j; // kembalikan sudut bawah nilai referensi setelah sortir bohong} public static void swap (objek [] arr, int i, int j) {if (i! = J) {objek temp = arr [i arr [i arr [i] {if (i! = J) {objek temp = arr [i arr [i arr [i) {if (i! printarr (objek [] arr) {for (objek o: arr) {system.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 9, 9, 8, 8, 8, 0, 0, 0; 0 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Penyortiran cepat terus mengoptimalkan: Gunakan penyortiran insert secara bersamaan
Pemesanan cepat adalah untuk terus mengurangi skala masalah untuk menyelesaikan sub-masalah dan membutuhkan rekursi yang berkelanjutan. Namun, rekursi cukup kecil, dan jika rekursi + yang tidak stabil ini terus dieksekusi, efisiensinya mungkin tidak terlalu baik.
Jadi, ketika masalahnya kecil dan hampir tertib, penyisipan penyisipan berkinerja baik. Anda sering dapat melihat komentar seperti itu di array.
Public Class quicksort {public static <t memperluas sebanding <? super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr array akan diurutkan* @param kiri tertutup* @param tepat di sebelah kanan* @param k ketika sortir cepat kembali ke dalam skala subproblem <= k, masukkan optimisasi @public @Toatic Toatic @Toatic Toatic Toatic To Ta -Toatic To To -Toatic To Toys To Toys To Toys To Toy To Toatic To Public To Public To Public To Public, memperluas yang sebanding <? super t >> void sort (t [] arr, int kiri, int kanan, int k) {// jam skala diurutkan dengan insersi if (kanan - kiri <= k) {insersionor (arr, kiri, kanan); return;} int p = partisi (arr, kiri, kanan); sort (arr, kiri, p - 1, k); sort, arr, p + 1, g + 1, g + 1, g + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, arr, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + 1, p + super T>> void insertionSort(T[] arr, int l, int r) {for (int i = l + 1; i <= r; i++) {T cur = arr[i];int j = i - 1;for (; j >= 0 && cur.compareTo(arr[j]) < 0; j--) {arr[j + 1] = arr[j];}arr[j + 1] = cur;}}private static <T memperluas yang sebanding <? super t >> int partisi (t [] arr, int kiri, int kanan) {// Sebelum menyortir, biarkan nilai referensi bertukar dengan nomor acak. Dengan cara ini, nilai referensi acak. // Ini tidak akan menyebabkan skala rekursif dari sisi kiri dan kanan tidak konsisten ketika array relatif pesanan, menghasilkan swap kompleksitas waktu terburuk (ARR, kiri, (int) (math.random () * (kanan - kiri + 1) + kiri)); t basis = ARR [kiri]; int J = untuk (int (int i = 1))); t base = arr [kiri]; int j = for (int i = i = i = i <) i {i oM = i {i oM = i {i ifor; 0) {j ++; swap (arr, j, i);}} swap (arr, kiri, j); return j; // kembalikan sudut bawah nilai dasar setelah berbaring penyortiran} public static void swap (objek [] arr, int i, int j) {if (i! = J) {objek temp = arr [i] {i] = arr [i]; printarr (objek [] arr) {for (objek o: arr) {system.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 9, 9, 8, 8, 8, 0, 0, 0; 0 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Penyortiran cepat terus mengoptimalkan: penyortiran cepat dua arah
Dalam penyortiran cepat normal awal, dikatakan bahwa nilai dasar di sisi kiri pangkalan lebih kecil dari pangkalan, sedangkan dasar di sisi kanan lebih besar dari atau sama dengan pangkalan. Ini sama dengan pangkalan akan berkumpul ke kanan (atau sedikit mengubah hubungan ukuran akan berkumpul ke kiri). Bagaimanapun, itu akan berkumpul. Ketika banyak angka diulang dalam array, itu akan menyebabkan perbedaan besar dalam ukuran kedua kapal selam. Pada saat ini, saya ingin menetapkan angka yang sama dengan pangkalan ke kedua sisi pangkalan, alih -alih menyatukannya.
(Catatan: Saat menguji kode, yang terbaik adalah memalingkan muka dari bagian penyisipan dan terlihat seperti pada kode saya di bawah ini ... jika tidak, ketika volume data kurang dari k = 16, sortir penyisipan dilakukan ...)
Public Class quicksort {public static <t memperluas sebanding <? super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr array akan diurutkan* @param kiri tertutup* @param tepat di sebelah kanan* @param k ketika sortir cepat kembali ke dalam skala subproblem <= k, masukkan optimisasi @public @Toatic Toatic @Toatic Toatic Toatic To Ta -Toatic To To -Toatic To Toys To Toys To Toys To Toy To Toatic To Public To Public To Public To Public, memperluas yang sebanding <? super t >> void sort (t [] arr, int kiri, int right, int k) {// insersionor (arr, kiri, kanan); // return; //} if (kiri> = kanan) kembali; int p = partisi (arr, kiri, kanan); sort (arr, kiri, kanan); sort (arr, kiri, p - 1, kidal); sortir (arr, kiri, kanan); urutkan (arr, kiri, p - 1, kidal); sortir, p + p + 1, sort, arr, kiri, p - p - 1, ke); sort) <arr, p + p + 1, sort, arr, left, p - p - p - k); sort (pr, p + p + 1, sort, arr, left, p - p - p -1, sort); sort) <arr, p + p +); super T>> void insertionSort(T[] arr, int l, int r) {for (int i = l + 1; i <= r; i++) {T cur = arr[i];int j = i - 1;for (; j >= 0 && cur.compareTo(arr[j]) < 0; j--) {arr[j + 1] = arr[j];}arr[j + 1] = cur;}}private static <T memperluas yang sebanding <? super t >> int partisi (t [] arr, int kiri, int kanan) {// Sebelum menyortir, biarkan nilai referensi bertukar dengan nomor acak. Dengan cara ini, nilai referensi acak. // Ini tidak akan menyebabkan skala rekursif sisi kiri dan kanan tidak konsisten ketika array relatif dipesan, menghasilkan swap kompleksitas waktu terburuk (ARR, kiri, (int) (matematika.random () * (kanan - kiri + 1) Kiri)); t base = ARR [kiri]; // Nilai dasar, lempar nilai referensi ini setiap kali, lihatlahnya, lihatlah sebagai Nilai Referensi ini setiap kali, lihat ini, LIFT TERJADI KALI, LIGHT KIRI = ARR [ARR [KIRI]; // Nilai Dasar, Lemparkan Nilai Referensi ini setiap kali, LIHAT KALI, LIHAT KALI)); ARR [ARR [kiri]; 1; // untuk interval [kiri+1 ......... kanan] yang disebutkan di baris sebelumnya, maksud saya [kiri+1 ...... i) Interval terbuka kanan tertutup kiri kurang dari atau sama dengan basis. int j = kanan; // untuk interval [kiri+1 ...... kanan] yang disebutkan dalam dua baris sebelumnya, J berarti bahwa nilai -nilai (j ...... kanan] interval tertutup terbuka dan kanan lebih besar dari atau sama dengan pangkalan. Sementara (true) {// scan dari kiri ke kanan, memindai elemen pertama lebih besar dari pangkalan, dan kemudian saya berhenti di sana. Sementara (i <= kanan & scan [i]. Kiri, pindai elemen pertama yang lebih kecil dari pangkalan, dan kemudian J berhenti di sana. penyortiran} public static void swap (objek [] arr, int i, int j) {if (i! = j) {objek temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private static printarr (objek [] arr) {untuk (objek o: arr) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Lanjutkan untuk mengoptimalkan penyortiran cepat: dua penyortiran cepat tidak memerlukan swap, gunakan Exchange
Ketika dua jalur di atas menemukan nilai lebih besar dari dasar dan nilai kurang dari basis, mereka menggunakan metode swap () untuk bertukar. Pertukaran dua digit melibatkan pengoperasian suhu variabel ketiga, dengan lebih banyak operasi baca dan tulis. Selanjutnya, gunakan metode penugasan langsung untuk menempatkan kurang dari di sebelah kanan dan lebih besar dari di sebelah kiri. Ketika saya dan J bertemu, posisi itu adalah tempat pangkalan harus ditempatkan. Perjalanan ini selesai. Hanya berulang.
Public Class quicksort {public static <t memperluas sebanding <? super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr array akan diurutkan* @param kiri tertutup* @param tepat di sebelah kanan* @param k ketika sortir cepat kembali ke dalam skala subproblem <= k, masukkan optimisasi @public @Toatic Toatic @Toatic Toatic Toatic To Ta -Toatic To To -Toatic To Toys To Toys To Toys To Toy To Toatic To Public To Public To Public To Public, memperluas yang sebanding <? super t >> void sort (t [] arr, int kiri, int right, int k) {// insersionor (arr, kiri, kanan); // return; //} if (kiri> = kanan) kembali; int p = partisi (arr, kiri, kanan); sort (arr, kiri, kanan); sort (arr, kiri, p - 1, kidal); sortir (arr, kiri, kanan); urutkan (arr, kiri, p - 1, kidal); sortir, p + p + 1, sort, arr, kiri, p - p - 1, ke); sort) <arr, p + p + 1, sort, arr, left, p - p - p - k); sort (pr, p + p + 1, sort, arr, left, p - p - p -1, sort); sort) <arr, p + p +); super T>> void insertionSort(T[] arr, int l, int r) {for (int i = l + 1; i <= r; i++) {T cur = arr[i];int j = i - 1;for (; j >= 0 && cur.compareTo(arr[j]) < 0; j--) {arr[j + 1] = arr[j];}arr[j + 1] = cur;}}private static <T memperluas yang sebanding <? super t >> int partisi (t [] arr, int kiri, int kanan) {// Sebelum menyortir, biarkan nilai referensi bertukar dengan nomor acak. Dengan cara ini, nilai referensi acak. // Ini tidak akan menyebabkan skala rekursif sisi kiri dan kanan tidak konsisten ketika array relatif dipesan, menghasilkan swap kompleksitas waktu terburuk (ARR, kiri, (int) (matematika. Kiri; // Untuk interval [kiri+1 ......... kanan] yang disebutkan di baris sebelumnya, maksud saya [kiri+1 ...... i) Nilai interval tertutup kanan tertutup kiri kurang dari atau sama dengan basis. int j = kanan; // untuk interval [kiri+1 ...... kanan] yang disebutkan dalam dua baris sebelumnya, J berarti bahwa nilai-nilai (j ...... kanan] interval terbuka dan tertutup kanan lebih besar dari atau sama dengan pangkalan. Sementara (i <j) {// pindai dari kanan ke kiri, pemindaian kios pertama dari pangkalan, dan kemudian j stop di sana. j-; arr [i] = arr [j]; // pindai dari kiri ke kanan, pindai elemen pertama lebih besar dari pangkalan, dan kemudian saya berhenti di sana. i, int j) {if (i! = j) {objek temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private static void printarr (objek [] arr) {for (objek o: arr) {System.out.print (o); System.out.print ("/t"); args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); // 3 5 1 7 2 9 8 0 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Penyortiran cepat terus mengoptimalkan: Ketika sejumlah besar data dan banyak pengulangan digunakan, gunakan penyortiran cepat tiga arah
Bagilah array menjadi tiga jalur. Jalur pertama lebih kecil dari pangkalan, jalur kedua sama dengan pangkalan, dan jalur ketiga lebih besar dari pangkalan.
Gunakan pointer untuk memindai dari depan ke belakang, jika:
1. Angka yang ditunjuk oleh CUR kurang dari basis, lalu: pertukaran nilai arr [cur] dan arr [i], dan kemudian i ++, cur ++.
2. Angka yang ditunjuk oleh CUR sama dengan basis, lalu: Cur ++
3. Angka yang ditunjuk oleh CUR lebih besar dari basis, lalu: pertukaran nilai ARR [cur] dan arr [j], dan kemudian j--.
Ketika Cur> j, itu berarti bahwa ketiga jalur telah selesai.
Public Class quicksort {public static <t memperluas sebanding <? super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param arr array akan diurutkan* @param kiri tertutup* @param tepat di sebelah kanan* @param k ketika sortir cepat kembali ke dalam skala subproblem <= k, masukkan optimisasi @public @taP -tuan @public To @Toatic To Toatic To Toatic To Toys To Toy To To Public To Toatic To Public To Public, memperluas yang sebanding <? super t >> void sort (t [] arr, int kiri, int right, int k) {// insersionor (arr, kiri, kanan); // return; //} if (kiri> = kanan) kembali; int [] ret = partisi (arr, kiri, kanan); sort (arr, kiri, ret [0], k); sort (arr, arr, ret [1], kanan); sort (arr, arr, ret [0], k); sort (arr, arr, ret [1], kidal); super T>> void insertionSort(T[] arr, int l, int r) {for (int i = l + 1; i <= r; i++) {T cur = arr[i];int j = i - 1;for (; j >= 0 && cur.compareTo(arr[j]) < 0; j--) {arr[j + 1] = arr[j];}arr[j + 1] = cur;}}/** * @param arr array yang akan diurutkan* @param meninggalkan batas kiri array yang akan diurutkan* @param kanan batas kanan array yang akan diurutkan* @param <t> generik* @return*/private static <t meluas sebanding <? super t >> int [] partisi (t [] arr, int kiri, int kanan) {// sebelum menyortir, biarkan nilai referensi ditukar dengan nomor acak. Dengan cara ini, nilai referensi acak. // Ini tidak akan menyebabkan skala rekursif pada sisi kiri dan kanan tidak konsisten ketika array relatif pesanan, menghasilkan pertukaran kompleksitas waktu terburuk (ARR, kiri, (int) (matematika. dibagi menjadi tiga saluran berikut (interval) int i = kiri; // kiri menunjukkan bahwa [lLEFT ... kiri) Angka -angka dalam interval terbuka kanan tertutup kiri lebih kecil dari basis int j = kanan; // menunjukkan bahwa (rright ... kanan] angka -angka di kiri dan interval tertutup lebih besar dari basis int cur = i; // gunakan cur untuk melintasi array. <= j) {if (arr[cur].compareTo(base) == 0) {cur++;} else if (arr[cur].compareTo(base) < 0) {swap(arr, cur++, i++);} else {swap(arr, cur, j--);}} return new int[]{i - 1, j + 1};//[i...j] are all equal to base, and the Sub-masalah hanya perlu menyelesaikan swap void statis public kiri dan kanan i dan j} public static void (objek [] arr, int i, int j) {if (i! = j) {objek temp = arr [i]; arr [i] = arr [j]; arr [j] = Temp;}} private static void printarr (Object [] arr) {arr) {arr) untuk (arr) untuk (arr) {arr) {o) {o) {o) o (o) {o) {o) {o) {o) {o) {o) {o) {o) = arr [j) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {integer [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Meringkaskan
Di atas adalah semua penjelasan terperinci dari Implementasi Pemrograman Java Kode Penyortiran dan Optimalisasi Cepat. Saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!