排序
package com.chinasoft.imssreport.controller.yang.util;
import java.util.Arrays;
import java.util.Random;
/**
* 算法工具类
* @author wWX598039
*
*/
public class algorithmUtil {
/**
* int[] 选择排序 空间复杂度O(1) 时间复杂度 O(n^2)
* @param arr:待排序int[]
* @param sortRule:排序规则
* @return
*/
public static int[] selectSort(int[] arr, String sortRule) {
for(int j=0;j<arr.length-1;j++) {
int minPosition = j;
for(int i=j+1;i<arr.length;i++) {
minPosition = arr[i]<arr[minPosition]?i:minPosition;
}
algorithmUtil.swap(arr, minPosition, j);
System.out.println("第"+j+"次循环后数组为:");
algorithmUtil.print(arr);
}
return arr ;
}
/**
* 冒泡排序 空间复杂度O(1) 时间复杂度 O(n^2)
* @param arr
* @return
*/
public static int[] BubbleSort(int[] arr) {
boolean sign = false; //产生交换会置为true
for(int i=0;i<arr.length-1;i++) {
for(int j=0;j<arr.length-1-i;j++) {
if(arr[j]>arr[j+1]) {
algorithmUtil.swap(arr, j, j+1);
sign = true;
}
}
if(sign==false) {
System.out.println("优化在第"+i+"次生效");
return arr;
}
System.out.println("第"+ i +"次循环后数组为:");
algorithmUtil.print(arr);
sign = false;
}
return arr;
}
/**
* 插入排序 空间复杂度O(1) 时间复杂度 O(n^2)
* @param arr
* @return
*/
public static int[] InsertSort(int[] arr) {
for(int i=1;i<arr.length;i++) {
for(int j=i;j>0;j--) {
if(arr[j]<arr[j-1]) {
algorithmUtil.swap(arr, j, j-1);
}
}
System.out.println("第"+ i +"次循环后数组为:");
algorithmUtil.print(arr);
}
return arr;
}
/**
* 希尔排序 空间复杂度O(1) 时间复杂度 O(n^1.3)
* @param arr
* @return
*/
public static int[] ShellSort(int[] arr) {
int h = algorithmUtil.getKnuth(arr);
for(int gap = h;gap>0;gap=(gap-1)/3) { //gap-1)/3细节不用在意
for(int i=gap;i<arr.length;i++) {
for(int j=i;j>gap-1;j-=gap) { //gap-1 就是第一个插排元素的前一个元素
if(arr[j]<arr[j-gap]) {
algorithmUtil.swap(arr, j, j-gap);
}
}
System.out.println("第"+ i +"次循环后数组为:");
algorithmUtil.print(arr);
}
}
return arr;
}
/**
* 归并排序 :将数组分解成最小单元,递归合并
* @param arr
* @param leftPointer 左指针
* @param rightPointer 右指针
* @param rightBoundary 右边界(数组下标值)
* @return
*/
public static void mergeSort(int[] arr,int left,int right) {
if(left == right)return;
//分成两半
int mid = left+(right-left)/2; //右半边的指标
//左边排序
algorithmUtil.mergeSort(arr, left, mid-1);
//右边排序
algorithmUtil.mergeSort(arr, mid, right);
//归并
algorithmUtil.sort(arr, left, mid, right);
}
/**
* 归并排序递归方法
* @param arr
* @param leftPointer
* @param rightPointer
* @param rightBoundary
* @return
*/
public static int[] sort(int[] arr, int leftPointer ,int rightPointer,int rightBoundary) {
int[] result = new int[rightBoundary-leftPointer+1];
int i = leftPointer;
int j = rightPointer;
int k = 0;
while(i<=rightPointer-1 && j<=rightBoundary) {
result[k++] = arr[i]<= arr[j]?arr[i++]:arr[j++];
}
while(i <=rightPointer-1) {
result[k++] = arr[i++];
}
while(j <= rightBoundary) {
result[k++] = arr[j++];
}
return arr;
}
//打印数组值
public static void print(int[] arr) {
for(int i =0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println("");
}
//数组元素互换
public static int[] swap(int[] arr,int i,int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return arr;
}
//获取数组的Knuth值
public static int getKnuth(int[] arr) {
int h = 1;
while(h<=arr.length/3) {
h = h*3+1;
}
return h;
}
//排序验证
public static void check() {
int[] arr1 = algorithmUtil.generateRandomArray();
int[] arr2 = new int[arr1.length];
System.arraycopy(arr1, 0, arr2, 0, arr1.length);
Arrays.sort(arr1);
algorithmUtil.ShellSort(arr2);
boolean same = true;
for(int i=0;i<arr1.length;i++) {
if(arr1[i]!=arr2[i]) {
same = false;
}
}
System.out.print(same);
}
//随机数组生成器
public static int[] generateRandomArray() {
Random r = new Random();
int[] arr = new int[100];
for(int i=0;i<arr.length;i++) {
arr[i] = r.nextInt(100);
}
return arr;
}
}