public static void selectionSort(int[] arr) {
if (arr == null || arr.length <= 0)
return;
heapSort(arr);
// simpleSelectSort(arr);
}
// 简单选择排序 从待排序中选择最值放入已排序部分末尾
public static void simpleSelectSort(int[] arr) {
// 代表已排序部分最后一个数
int end = -1;
// 未排序部分第一个数
int start = 0;
for (; start < arr.length; start++) {
int min = start;
for (int j = start + 1; j < arr.length; j++) {
min = arr[min] > arr[j] ? j : min;
}
swap(arr, min, ++end);
}
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 堆排序
public static void heapSort(int[] arr) {
// 构建大根堆(如果最终是求的递增序列)
buildHeap(arr);
// 交换堆顶和末尾,然后重新构建大根堆(注意大根堆范围缩小了)
int i = arr.length-1;
while (i>0){
swap(arr,0,i--);
down(arr,0,i);
}
}
public static void buildHeap(int[] arr) {
// PC
for (int i = arr.length - 1; i >= 0; i--) {
down(arr, i, arr.length - 1);
}
}
// end 可以达到的最后一个位置
public static void down(int[] arr, int index, int end) {
int parent = index;
int child = 2 * parent + 1;
while (child <= end) {
child = child + 1 <= end && arr[child + 1] > arr[child] ? child + 1 : child;
if (arr[parent] > arr[child]) {
break;
}
swap(arr, parent, child);
parent = child;
child = parent * 2 + 1;
}
}
题目:交换排序
public static void exchangeSort(int[] arr) {
if(arr == null || arr.length <= 1)
return;
//bubbleSort(arr);
fastSort(arr);
}
public static void bubbleSort(int[] arr){
int end = arr.length-1;
while (end>0){
// 每次将最大移动到末尾
for (int i = 0;i<end;i++){
if(arr[i] > arr[i+1]){
swap(arr,i,i+1);
}
}
end--;
}
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void fastSort(int[] arr){
process(arr,0,arr.length-1);
}
// 将待排序部分划分为更小部分
public static void process(int[] arr,int start,int end){
if(start>=end)
return;
int index = start + ((int)(Math.random()*(end-start+1)));
int piv = arr[index];
int[] pivort = pivort(arr, start, end,piv);
process(arr,start,pivort[0]-1);
process(arr,pivort[1]+1,end);
}
// 将指定范围数组划分为三个部分,左边小于piv 中间等于 右边大于 返回等于piv的范围
public static int[] pivort(int[] arr,int start,int end,int piv){
// 代表小于piv最后一个元素下标
int less = start -1;
// 代表大于piv部分第一个元素下标
int more = end+1;
int cur = start;
while (cur<more){
if(arr[cur] == piv){
cur++;
}else if (arr[cur] < piv){
++less;
swap(arr,cur,less);
cur++;
}else {
-- more;
swap(arr,cur,more);
}
}
return new int[]{less+1,more-1};
}
题目:插入排序
// 直接插入排序
// 未排序部分首个元素,直接插入已排序部分
public static void directInsertSort(int[] arr){
if(arr == null || arr.length <=1)
return;
int cur = 1;
while (cur<arr.length){
int tmp = arr[cur];
int pre = cur-1;
while (pre >=0 && arr[pre] >tmp ){
swap(arr,pre,pre+1);
pre--;
}
arr[pre+1] = tmp;
cur++;
}
}
public static void shellSort(int[] arr){
// PC
int offset = arr.length>>1;
while (offset >= 1){
for (int i = 0; i < offset; i++) {
// i 为当前已排序部分最后一个
// next 为未排序部分第一个
int next = i+offset;
while (next < arr.length){
int pre = next-offset;
int tmp = arr[next];
while (pre>=0 && arr[pre] > tmp ){
swap(arr,pre,pre+offset);
pre -= offset;
}
arr[pre+offset] = tmp;
next += offset;
}
}
offset >>= 1;
}
}
题目:归并排序
// 归并排序
// 递归将待排序数组划分为更小部分,直到长度为1直接返回,调用方将已排序子数组合并为递增数组
public static void mergeSort(int[] arr){
if (arr == null || arr.length<=1)
return;
process(arr,0,arr.length-1);
}
// 将待排序数组范围划分为更小的部分
public static void process(int[] arr,int start,int end){
if(start >= end)
return;
int mid = start +((int)(Math.random()*(end-start+1)));
process(arr,start, mid);
process(arr,mid+1,end);
merge(arr,start,mid,end);
}
// 将mid分界的两个部分合并为一个有序的
public static void merge(int[] arr,int start,int mid,int end){
int[] help = new int[end - start + 1];
int index = 0;
int p1= start;
int p2 = mid+1;
while (p1<=mid && p2<=end){
while (p1<=mid && arr[p1] <= arr[p2]){
help[index++] = arr[p1++];
}
while (p2<=end && arr[p2] <= arr[p1]){
help[index++] = arr[p2++];
}
}
while (p2<=end){
help[index++] = arr[p2++];
}
while (p1 <= mid){
help[index++] = arr[p1++];
}
index = 0;
while (index < help.length){
arr[start+index] = help[index];
index++;
}
}