排序算法合集

先来个二分法查找:

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;
        }
      }
    };
  }

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值