📅  最后修改于: 2023-12-03 15:26:27.347000             🧑  作者: Mango
在编程过程中,我们常常需要对数组进行排序。不同的排序方法有不同的时间复杂度,但无论使用何种方法,都可以采取一些优化措施来最小化所需的步骤。
我们可以根据数组的大小、元素的类型和数据的分布情况等因素,选取合适的排序算法。
在选择合适的排序算法后,仍然可以通过一些优化措施来最小化所需的步骤。
快速排序算法是采用分治的思想实现的,它的核心是一次划分操作(partition),即将数组分为左右两部分,使得左部分所有元素都小于等于右部分的所有元素。因此,快速排序算法中选择pivot的策略对算法性能有很大影响。
常用的pivot选择策略有三种:
其中,中间元素的选择方式称为三数取中法。使用三数取中法可以避免pivot选的太小或太大的情况,使得产生的子问题更为平衡,从而提高算法的效率。
public static int medianOfThree(int[] array, int left, int right){
int mid = (left + right) / 2;
if(array[left] > array[mid]){
swap(array, left, mid);
}
if(array[left] > array[right]){
swap(array, left, right);
}
if(array[mid] > array[right]){
swap(array, mid, right);
}
//此时array[mid]为pivot
return array[mid];
}
插入排序算法可以看作是一种基于比较的排序算法,它的关键是比较操作。因此,如果能减少比较操作的次数,就能提高算法的效率。
我们可以将插入排序算法改进为二分插入排序算法。当插入一个元素时,我们可以使用二分查找法找到该元素应该插入的位置,进行插入操作。这样,比较操作的次数就减少了一半,从而提高算法的效率。
public static void binaryInsertSort(int[] array){
int n = array.length;
for(int i=1;i<n;i++){
//二分查找array[i]应该插入的位置
int left = 0,right = i-1;
while(left<=right){
int mid = (left+right)/2;
if(array[i]<array[mid]){
right = mid-1;
}
else{
left = mid+1;
}
}
//插入array[i]
int temp = array[i];
for(int j=i-1;j>=left;j--){
array[j+1] = array[j];
}
array[left] = temp;
}
}
归并排序算法也是一种基于比较的排序算法,它的关键是将两个有序数组合并成一个有序数组。如果合并的两个子数组已经有序,就可以直接跳过归并操作,从而提高算法的效率。
public static void merge(int[] array, int left, int mid, int right){
int[] temp = new int[right-left+1];
int index = 0,i = left,j = mid+1;
while(i<=mid && j<=right){
if(array[i]<=array[j]){
temp[index++] = array[i++];
}
else{
temp[index++] = array[j++];
}
}
while(i<=mid){
temp[index++] = array[i++];
}
while(j<=right){
temp[index++] = array[j++];
}
//将合并后的有序数组复制到array中
System.arraycopy(temp,0,array,left,temp.length);
}
public static void mergeSort(int[] array, int left, int right){
if(left>=right){
return;//递归退出条件
}
if(right-left+1<=8){//默认8为插入排序的阈值
insertionSort(array,left,right);
return;
}
int mid = (left+right)/2;
mergeSort(array,left,mid);
mergeSort(array,mid+1,right);
if(array[mid]>array[mid+1]){
merge(array,left,mid,right);
}
}
如果机器有多个处理器或者是多核CPU,则可以使用多线程来实现并行排序算法。并行排序算法利用计算机的并行处理能力,将数组划分为多个子数组,每个处理器或核心负责对一个子数组进行排序,最后将子数组合并即可。
常见的并行排序算法包括:
//P-Quicksort示例
public static void parallelQuickSort(int[] array, int left, int right){
if(left>=right){
return;//递归退出条件
}
if(right-left+1<=1000){//默认1000为插入排序的阈值
insertionSort(array,left,right);
return;
}
int pivot = partition(array,left,right);
Thread leftThread = new Thread(new Runnable(){
public void run(){
parallelQuickSort(array, left, pivot-1);
}
});
Thread rightThread = new Thread(new Runnable(){
public void run(){
parallelQuickSort(array, pivot+1, right);
}
});
leftThread.start();
rightThread.start();
try{
leftThread.join();
rightThread.join();
}
catch(InterruptedException e){
e.printStackTrace();
}
}