先来个二分法查找:
public void binarySearch() {
int a = 3;
int[] arr = {0, 1, 2, 3, 5, 6, 7};
int i = biSearch(arr, a);
System.out.println(i);
}
public int biSearch(int[] arr, int a) {
int low = 0;
int high = arr.length - 1;
int mid;
while (low <= high) {
mid = (low + high) / 2;
if (arr[mid] == a) {
return mid + 1;
} else if (arr[mid] < a) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
冒泡排序:
前后比较,每轮锁定一个值在合适的位置.
public void test() {
int[] arr = {0, 1, 2, 13, -4, -1, 5, 6, 7};
bubbleSort(arr);
for (int i : arr) {
System.out.println(i);
}
}
public void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 1; j < arr.length; j++) {
if (arr[j] < arr[j - 1]) {
int tmp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = tmp;
}
}
}
}
冒泡排序优化一:
public void test() {
int[] arr = getArr();
// timeCost(bubbleSort(arr, arr.length),arr);//排序耗时:112.1193
int[] sortedArr = getSortedArr();
timeCost(bubbleSortOptimize1(sortedArr, sortedArr.length), arr);//排序耗时:0.16
for (int i : arr) {
System.out.println(i);
}
}
public Consumer bubbleSortOptimize1(int[] arr, int len) {
//优化1,对于 arr[] = {1,2,3,4,5,7,6}只需循环第一次移动一次即可有序
//从第二次循环开始没有移动.
//优化点:每次循环后都记录一下本次是否移动数字顺序
return e -> {
for (int i = 0; i < len; i++) {
boolean change = false;
for (int j = 1; j < len; j++) {
if (arr[j] < arr[j - 1]) {
int tmp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = tmp;
change = true;
}
}
if (change == false) {
break;
}
}
};
}
public void timeCost(Consumer consumer, int[] arr) {
long l = System.nanoTime();
consumer.accept(arr);
long l1 = System.nanoTime();
System.out.println("排序耗时:" + (l1 - l) / 1000000.0);
}
public int[] getArr() {
int[] arr = new int[10000];
Random random = new Random();
for (int i = 0; i < 10000; i++) {
arr[i] = random.nextInt(10000);
}
return arr;
}
public int[] getSortedArr() {
int[] arr = new int[10000];
for (int i = 0; i < 10000; i++) {
arr[i] = i;
}
return arr;
}
冒泡排序优化二:
public Consumer bubbleSortOptimize2(int[] arr, int len) {
//记录内层循环时最后调换顺序的位置,后面的数字都是有序的
//下次内层循环不用再遍历全部长度.
return e -> {
int index = len;
int tmp1 = 0;
for (int i = 0; i < len; i++) {
boolean change = false;
for (int j = 1; j < index; j++) {
if (arr[j] < arr[j - 1]) {
int tmp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = tmp;
change = true;
tmp1 = j;
}
}
index = tmp1;
if (change == false) {
break;
}
}
};
}
插入排序
import com.example.demo_for_gitee.util.TestUtil;
import java.util.function.Consumer;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;
@Slf4j
@RunWith(SpringRunner.class)
public class InsertSortTest {
@Test
public void test() {
int[] arr = TestUtil.getArr();
// TestUtil.timeCost(insertSort(arr, arr.length), arr);//排序耗时:19.5004
// TestUtil.timeCost(insertSort1(arr, arr.length), arr);//排序耗时:16.6843
// TestUtil.timeCost(insertSortOptimize1(arr, arr.length), arr);//改进不大
TestUtil.timeCost(insertSortOptimize2(arr, arr.length), arr);//将近30毫秒,确实是更慢了.
for (int i : arr) {
System.out.println(i);
}
}
public Consumer insertSort(int[] arr, int len) {
return e -> {
for (int i = 1; i < len; i++) {
int j = i;
//这样比较要交换很多次
while (j > 0 && arr[j] < arr[j - 1]) {
int tmp;
tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
j--;
}
}
};
}
public Consumer insertSort1(int[] arr, int len) {
return e -> {
for (int i = 1; i < len; i++) {
int j = i - 1;
int key = arr[i];
while (j >= 0 && key < arr[j]) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
};
}
public Consumer insertSortOptimize1(int[] arr, int len) {
return e -> {
for (int i = 1; i < len; i++) {
//如果当前值比前面的值大就不需要进行下面的比较
if (arr[i] < arr[i - 1]) {
int j = i - 1;
int key = arr[i];
while (j >= 0 && key < arr[j]) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
};
}
/**
* 内层循环使用二分查找
* @param arr
* @param len
* @return
*/
public Consumer insertSortOptimize2(int[] arr, int len) {
return e -> {
int low, mid, high, key,j;
for (int i = 1; i < len; i++) {
//如果当前值比前面的值大就不需要进行下面的比较
if (arr[i] < arr[i - 1]) {
key = arr[i];
low = 0;
high = i - 1;
while (low <= high) {
mid = (low + high) / 2;
if (arr[mid] > key) {
high = mid - 1;
} else {
low = mid + 1;
}
}
//从mid开始到i-1,都得后移
for(j=i-1;j>=low+1;j--){
arr[j+1]=arr[j];
}
arr[low] = key;
}
}
};
}
}