冒泡、选择、插入、归并、shell、快速排序
结果:从小到大排列
Bubble Sort
从左到右,相邻数据两两比较,右边数据小,则交换二者位置,每次将最大数据移至最右。
Select Sort
从左到右,用maxDex为索引的数据(最右未有序的数据)和前面每个数据进行比较,如比maxDex指向的数据大,则用其索引替换maxDex,最后交换索引为maxDex和当前最右未有序处的数据。
Insert Sort
假设某数据右边的数据是有序的,将其存储在temp中,与右边的数据从左往右依次比较,每次都将比它小的数据左移一位,直到插入比它大的数据前面或放在最右。
Insert(BinarySearch) Sort
在寻找未有序的数据的右侧位置时,使用二分查找。
Merge Sort
归并
Shell Sort
Insert sort h-增量排序
h=3*h+1
Quick Sort
划分
1.以最后一个数据为pivot。头、尾(pivot前一个)同时和pivot比较,头部不小于pivot的值和尾部不大于pivot的值互相交换。然后将pivot置于两组数之间(尾部的头部和pivot交换实现)。
2.以头中尾三个数据中,中等大小的为pivot。最小的置于头部,最大的置于尾部,pivot置于尾部左侧一位。头部右侧一位、尾(pivot前一个)同时和pivot比较……小于等于3个数据人工排序。
3.以头中尾三个数据中,中等大小的为pivot。小于等于10个数据用插入排序。
package sort;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class ArraySort {
public static int[] createIntArray(int size) {
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = (int) (Math.random() * size);
}
return a;
}
//这并不是一个很好的创建随机数组的方法
//当需要的随机数超过1000个就不能保证其是否有重复的数据
//float精确的不高
public static int[] createIntArrayNoRepeat(int min, int max) {
int length = max - min + 1;
int[] a = new int[length];
Set<Float> set = new HashSet<Float>();
Random rand = new Random();
for (int i = min; i < max+1; i++) {
set.add(i + rand.nextFloat());
}
int j = 0;
for (Float f : set) {
a[j++] = (int) f.floatValue();
}
return a;
}
public static void print(int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
public static int[] copyArray(int[] a) {
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
return b;
}
public static void bubbleSort(int[] a) {
for (int out = a.length - 1; out > 0; out--) {
for (int in = 0; in < out; in++) {
if (a[in] > a[in + 1]) {
int temp = a[in];
a[in] = a[in + 1];
a[in + 1] = temp;
}
}
}
}
public static void selectSort(int[] a) {
for (int out = a.length - 1; out > 0; out--) {
int max = out;
for (int in = 0; in < out; in++) {
if (a[in] > a[max]) {
max = in;
}
}
int temp1 = a[out];
a[out] = a[max];//最大值放在右侧
a[max] = temp1;
}
}
//
public static void insertSort(int[] a) {
if (a == null) {
return;
}
for (int out = a.length - 1; out > 0; out--) {
int tempValue = a[out - 1];
for (int in = out; in < a.length; in++) {
if (tempValue > a[in]) {
a[in - 1] = a[in];
if (in == a.length - 1) {
a[in] = tempValue;
}
} else {
a[in - 1] = tempValue;
break;
}
}
}
}
//
public static void insertSortWithBinarySearch(int[] a) {
if (a == null) {
return;
}
for (int out = a.length - 1; out > 0; out--) {
int tempValue = a[out - 1];
int leftDex = out;
int rightDex = a.length;
int mid = 0;
while (leftDex < rightDex) {
mid = (leftDex + rightDex) >>> 1;
if (tempValue > a[mid]) {
leftDex = mid + 1;
} else if (tempValue < a[mid]) {
rightDex = mid;
} else {
// 可以有重复的数据,但是不保证重复数据的先后位置(不稳定的)
break;
}
}
int sDex = 0;
// 没找到,这时 leftDex==rightDex is true,插入的数据一定比索引为leftDex的数小
if (leftDex == rightDex) {
sDex = leftDex;
} else {
// 找到与这个数据相同的数据,放在其左或右从结果来看都是一样的
sDex = mid;
}
for (int i = out; i < sDex; i++) {
a[i - 1] = a[i];
}
a[sDex - 1] = tempValue;
}
}
private static void insertSort(int[] a, int low, int high) {
if (a == null) {
return;
}
for (int out = high; out > low; out--) {
int tempValue = a[out - 1];
for (int in = out; in <= high; in++) {
if (tempValue > a[in]) {
a[in - 1] = a[in];
if (in == high) {
a[in] = tempValue;
}
} else {
a[in - 1] = tempValue;
break;
}
}
}
}
//
public static void mergeSort(int[] a) {
if (a.length == 0 || a.length == 1) {
return;
}
int[] tempArray = new int[a.length];
sort(a, 0, a.length - 1, tempArray);
}
private static void sort(int[] a, int lowerBound, int upperBound,
int[] tempArray) {
if (lowerBound == upperBound) {
return;
}
int mid = (lowerBound + upperBound) >>> 1;
sort(a, lowerBound, mid, tempArray);
sort(a, mid + 1, upperBound, tempArray);
merge(a, lowerBound, mid + 1, upperBound, tempArray);
}
private static void merge(int[] a, int lowDex, int highDex, int upperBound,
int[] temp) {
int tempArrayDex = lowDex;
int lowerBound = lowDex;
int lowPartUpperBound = highDex - 1;
while (lowDex <= lowPartUpperBound && highDex <= upperBound) {
if (a[lowDex] <= a[highDex]) {
temp[tempArrayDex++] = a[lowDex++];
} else {
temp[tempArrayDex++] = a[highDex++];
}
}
while (lowDex <= lowPartUpperBound) {
temp[tempArrayDex++] = a[lowDex++];
}
while (highDex <= upperBound) {
temp[tempArrayDex++] = a[highDex++];
}
for (int i = lowerBound; i < upperBound + 1; i++) {
a[i] = temp[i];
}
}
//
public static void shellSort(int[] a) {
if (a == null) {
return;
}
int h = 1;
while (h < a.length / 3) {
h = h * 3 + 1;
}
while (h > 0) {
for (int out = a.length - 1; out >= h; out--) {
int tempValue = a[out - h];
for (int in = out; in < a.length; in += h) {
if (tempValue > a[in]) {
a[in - h] = a[in];
if (in + h >= a.length) {
a[in] = tempValue;
}
} else {
a[in - h] = tempValue;
break;
}
}
}
h = (h - 1) / 3;
}
}
// 以最右一个值为pivot
public static void quickSort1(int[] a) {
if (a == null || a.length <= 1) {
return;
}
reFast1(a, 0, a.length - 1);
}
private static void reFast1(int[] a, int low, int high) {
if (low < high) {
int mid = partition1(a, low, high, a[high]);// 以最右一个值为pivot
reFast1(a, low, mid - 1);
reFast1(a, mid + 1, high);
}
}
private static int partition1(int[] a, int low, int high, int pivot) {
int left = low;
int right = high - 1;// pivot is not included
while (true) {
while (a[left] < pivot) {// when left=high or a[left]=pivot then
// break
left++;
}
while (right > left && a[right] > pivot) {// right>left is needed
right--;
}
if (left < right) {
swap(a, left, right);
left++;
} else {
break;
}
}
swap(a, left, high);// small array, pivot, big array
return left;
}
// 以第一个、中间以及最后一个值中的中等大小的值为pivot
public static void quickSort2(int[] a) {
if (a == null || a.length <= 1) {
return;
}
reFast2(a, 0, a.length - 1);
}
private static void reFast2(int[] a, int low, int high) {
if ((high - low) <= 0) {// <= 1个
return;
}
if ((high - low) <= 2) {// 2、3个
manualSort(a, low, high);
return;
}
int pivot = medianOf3(a, low, high);
int mid = partition2(a, low, high, pivot);
reFast2(a, low, mid - 1);
reFast2(a, mid + 1, high);
}
private static int partition2(int[] a, int low, int high, int pivot) {
int left = low + 1;
int right = high - 2;// a[high-1]=pivot,a[high]>=pivot
while (true) {
while (a[left] < pivot) {// when left=high-1,or a[left]>=pivot then
// break
left++;
}
while (a[right] > pivot) {// when right=low or a[right]<=pivot then
// break
right--;
}
if (left < right) {
swap(a, left, right);
left++;
} else {
break;
}
}
swap(a, left, high - 1);
return left;
}
private static void manualSort(int[] a, int low, int high) {
if (high - low == 1) {
if (a[low] > a[high]) {
int temp = a[low];
a[low] = a[high];
a[high] = temp;
}
} else if (high - low > 1) {
int mid = (high + low) >>> 1;
if (a[low] > a[mid]) {
swap(a, low, mid);
}
if (a[mid] > a[high]) {
swap(a, mid, high);
}
if (a[low] > a[mid]) {
swap(a, low, mid);
}
}
}
private static int medianOf3(int[] a, int low, int high) {
manualSort(a, low, high);
int mid = (high + low) >>> 1;
swap(a, mid, high - 1);
// swap(a,high-1,high);
return a[high - 1];
}
// 对于length小于等于10的采用插入排序
public static void quickSort3(int[] a) {
if (a == null || a.length <= 1) {
return;
}
reFast3(a, 0, a.length - 1);
}
private static void reFast3(int[] a, int low, int high) {
if (low == high) {
} else if ((high - low) < 10) {
insertSort(a, low, high);
} else {
int pivot = medianOf3(a, low, high);
int mid = partition2(a, low, high, pivot);
reFast3(a, low, mid - 1);
reFast3(a, mid, high);
}
}
private static void swap(int[] a, int dex1, int dex2) {
int temp = a[dex1];
a[dex1] = a[dex2];
a[dex2] = temp;
}
}