퀵 정렬 알고리즘 개념
퀵 정렬은 일반적으로 재귀 구현을 기반으로 합니다. 아이디어는 다음과 같습니다.
1. "피벗"이라고 하는 적절한 값(이상적으로는 중앙값이 가장 좋지만 구현에서는 일반적으로 배열의 첫 번째 값이 사용됨)을 선택합니다.
2. 이 값을 기준으로 배열을 두 부분으로 나눕니다. 작은 부분이 왼쪽에, 큰 부분이 오른쪽에 있습니다.
3. 이번 라운드가 끝나면 이 피벗의 위치가 최종 위치에 있어야 합니다.
4. 각 배열에 하나의 요소만 포함될 때까지 두 개의 하위 배열에 대해 위 프로세스를 반복합니다.
5. 정렬이 완료되었습니다.
기본 구현 방법:
public static void quickSort(int[] arr){ qsort(arr, 0, arr.length-1); } private static void qsort(int[] arr, int low, int high){ if (low < high){ int pivot=partition(arr, low, high); //将数组分为两部分 qsort(arr, low, pivot-1); //递归排序左子数组 qsort(arr, pivot+1, high); //递归排序右子数组 } } private static int partition(int[] arr, int low, int high){ int pivot = arr[low]; //枢轴记录 while (low<high){ while (low<high && arr[high]>=pivot) --high; arr[low]=arr[high]; //交换比枢轴小的记录到左端 while (low<high && arr[low]<=pivot) ++low; arr[high] = arr[low]; //交换比枢轴小的记录到右端 } //扫描完成,枢轴到位 arr[low] = pivot; //返回的是枢轴的位置 return low; }
제네릭을 사용하여 빠른 정렬 알고리즘 구현
다음을 포함하여 아래 QuickSort 클래스를 설계합니다. 정적 함수 sort()는 모든 유형의 배열을 정렬할 수 있습니다. 객체 유형의 배열인 경우 객체 유형은 CompareTo 함수를 사용하여 비교할 수 있도록 Comparable 인터페이스를 구현해야 합니다.
가장 기본적인 퀵 정렬 알고리즘을 최적화 없이 사용합니다.
소스 코드는 다음과 같습니다.
import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Random; public class QuickSort { @SuppressWarnings("unchecked") //对上述快排函数原型修改,使其可以对任意对象类型数组进行排序。这个函数为内部使用,外部排序函数接口为sort(),sort函数要求对象必须实现Comparable接口,可以提供编译时类型检测,见后文。 private static void quickSort(Object[] in,int begin, int end) { if( begin == end || begin == (end-1) ) return; Object p = in[begin]; int a = begin +1; int b = a; for( ; b < end; b++) { //该对象类型数组必须实现Comparable接口,这样才能使用compareTo函数进行比较 if( ((Comparable<Object>)in[b]).compareTo(p) < 0) { if(a == b){a++; continue;} Object temp = in[a]; in[a] = in[b]; in[b] = temp; a++; } } in[begin] = in[a-1]; in[a-1] = p; if( a-1 > begin){ quickSort(in,begin, a); } if( end-1 > a ) { quickSort(in,a, end); } return; } //使用泛型,对任意对象数组排序,该对象类型数组必须实现Comparable接口 public static <T extends Comparable<? super T>> void sort(T[] input){ quickSort(input,0,input.length); } //添加对List对象进行排序的功能,参考了Java中的Java.util.Collections类的sort()函数 public static <T extends Comparable<? super T>> void sort(List<T> list){ Object[] t = list.toArray();//将列表转换为数组 quickSort(t,0,t.length); //对数组进行排序 //数组排序完成后再写回到列表中 ListIterator<T> i = list.listIterator(); for (int j=0; j<t.length; j++) { i.next(); i.set((T)t[j]); } } //由于Java中原始数据类型(int、double、byte等)无法使用泛型,所以只能使用函数重载机制实现对这些原始类型数组(int[]、double[]、byte[]等)的排序。这里为了共用同一个排序函数,利用原始类型的(AutoBoxing,UnBoxing)机制将其封装为对应对象类型,组成新的对象数组,排序后再解封装,这样的缺点是需要额外的转换步骤、额外的空间保存封装后的数组。另一种方式是将排序代码复制到各个重载函数中,官方API中的Java.util.Arrays这个类中的sort()函数就是使用这种方法,可以从Arrays类的源代码看出。 public static void sort(int[] input){ Integer[] t = new Integer[input.length]; for(int i = 0; i < input.length; i++){ t[i] = input[i];//封装 } quickSort(t,0,t.length);//排序 for(int i = 0; i < input.length; i++){ input[i] = t[i];//解封装 } } //double[]数组的重载函数 public static void sort(double[] input){ Double[] t = new Double[input.length]; for(int i = 0; i < input.length; i++){ t[i] = input[i]; } quickSort(t,0,t.length); for(int i = 0; i < input.length; i++){ input[i] = t[i]; } } //byte[]数组的重载函数 public static void sort(byte[] input){ Byte[] t = new Byte[input.length]; for(int i = 0; i < input.length; i++){ t[i] = input[i]; } quickSort(t,0,t.length); for(int i = 0; i < input.length; i++){ input[i] = t[i]; } } //short[]数组的重载函数 public static void sort(short[] input){ Short[] t = new Short[input.length]; for(int i = 0; i < input.length; i++){ t[i] = input[i]; } quickSort(t,0,t.length); for(int i = 0; i < input.length; i++){ input[i] = t[i]; } } //char[]数组的重载函数 public static void sort(char[] input){ Character[] t = new Character[input.length]; for(int i = 0; i < input.length; i++){ t[i] = input[i]; } quickSort(t,0,t.length); for(int i = 0; i < input.length; i++){ input[i] = t[i]; } } //float[]数组的重载函数 public static void sort(float[] input){ Float[] t = new Float[input.length]; for(int i = 0; i < input.length; i++){ t[i] = input[i]; } quickSort(t,0,t.length); for(int i = 0; i < input.length; i++){ input[i] = t[i]; } } //测试用的main函数 public static void main(String[] args) { //生产一个随机数组成的int[]数组,用来测试 int LEN = 10; int[] input = new int[LEN]; Random r = new Random(); System.out.print("int[] before sorting: "); for(int i = 0; i < input.length; i++) { input[i] = r.nextInt(10*LEN); System.out.print(input[i] + " "); } System.out.println(); System.out.print("int[] after sorting: "); sort(input); for(int i : input) { System.out.print(i + " "); } System.out.println(); //生成一个字符串数组,用来测试 String[] s = new String[]{"b","a","e","d","f","c"}; System.out.print("String[] before sorting: "); for(int i = 0; i < s.length; i++) { System.out.print(s[i] + " "); } System.out.println(); System.out.print("String[] after sorting: "); sort(s); for(int i = 0; i < s.length; i++) { System.out.print(s[i] + " "); } System.out.println(); //生成一个字符串列表,用来测试 List<String> l = new LinkedList<String>(); s = new String[]{"b","a","e","d","f","c"}; System.out.print("LinkedList<String> before sorting: "); for (int j=0; j<s.length; j++) { l.add(s[j]); System.out.print(s[j] + " "); } System.out.println(); sort(l); System.out.print("LinkedList<String> after sorting: "); for (String ts : l) { System.out.print(ts + " "); } System.out.println(); } }
주 함수 테스트를 실행하면 QuickSort 클래스가 정상적으로 작동하는 것을 확인할 수 있습니다.
int[] before sorting: 65 48 92 26 3 8 59 21 16 45 int[] after sorting: 3 8 16 21 26 45 48 59 65 92 String[] before sorting: b a e d f c String[] after sorting: a b c d e f LinkedList<String> before sorting: b a e d f c LinkedList<String> after sorting: a b c d e f
자바에 대한 자세한 내용은 제네릭을 사용하여 빠른 정렬 알고리즘을 구현하는 방법에 대한 관련 기사를 보려면 PHP 중국어 웹사이트에 주목하세요!