- 希尔排序
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法
package sortdemo;
import java.util.Arrays;
/**
* Created by chengxiao on 2016/11/24.
*/
public class ShellSort {
public static void main(String []args){
int []arr ={1,4,2,7,9,8,3,6};
sort(arr);
System.out.println(Arrays.toString(arr));
int []arr1 ={1,4,2,7,9,8,3,6};
sort1(arr1);
System.out.println(Arrays.toString(arr1));
}
/**
* 希尔排序 针对有序序列在插入时采用交换法
* @param arr
*/
public static void sort(int []arr){
//增量gap,并逐步缩小增量
for(int gap=arr.length/2;gap>0;gap/=2){
//从第gap个元素,逐个对其所在组进行直接插入排序操作
for(int i=gap;i<arr.length;i++){
int j = i;
while(j-gap>=0 && arr[j]<arr[j-gap]){
//插入排序采用交换法
swap(arr,j,j-gap);
j-=gap;
}
}
}
}
/**
* 希尔排序 针对有序序列在插入时采用移动法。
* @param arr
*/
public static void sort1(int []arr){
//增量gap,并逐步缩小增量
for(int gap=arr.length/2;gap>0;gap/=2){
//从第gap个元素,逐个对其所在组进行直接插入排序操作
for(int i=gap;i<arr.length;i++){
int j = i;
int temp = arr[j];
if(arr[j]<arr[j-gap]){
while(j-gap>=0 && temp<arr[j-gap]){
//移动法
arr[j] = arr[j-gap];
j-=gap;
}
arr[j] = temp;
}
}
}
}
/**
* 交换数组元素
* @param arr
* @param a
* @param b
*/
public static void swap(int []arr,int a,int b){
arr[a] = arr[a]+arr[b];
arr[b] = arr[a]-arr[b];
arr[a] = arr[a]-arr[b];
}
}
- 快排
快速排序(Quicksort)是对冒泡排序算法的一种改进;
快速排序算法通过多次比较和交换来实现排序,其排序流程如下: [2]
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。 [2]
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。 [2]
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。 [2]
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
/**
* 快速排序,使得整数数组 arr 有序
*/
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
/**
* 快速排序,使得整数数组 arr 的 [L, R] 部分有序
*/
public static void quickSort(int[] arr, int L, int R) {
if(L < R) {
// 把数组中随机的一个元素与最后一个元素交换,这样以最后一个元素作为基准值实际上就是以数组中随机的一个元素作为基准值
swap(arr, new Random().nextInt(R - L + 1) + L, R);
int[] p = partition(arr, L, R);
quickSort(arr, L, p[0] - 1);
quickSort(arr, p[1] + 1, R);
}
}
/**
* 分区的过程,整数数组 arr 的[L, R]部分上,使得:
* 大于 arr[R] 的元素位于[L, R]部分的右边,但这部分数据不一定有序
* 小于 arr[R] 的元素位于[L, R]部分的左边,但这部分数据不一定有序
* 等于 arr[R] 的元素位于[L, R]部分的中间
* 返回等于部分的第一个元素的下标和最后一个下标组成的整数数组
*/
public static int[] partition(int[] arr, int L, int R) {
int basic = arr[R];
int less = L - 1;
int more = R + 1;
while(L < more) {
if(arr[L] < basic) {
swap(arr, ++less, L++);
} else if (arr[L] > basic) {
swap(arr, --more, L);
} else {
L++;
}
}
return new int[] { less + 1, more - 1 };
}
/*
* 交换数组 arr 中下标为 i 和下标为 j 位置的元素
*/
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}