第1节.pptx

1 排序算法

题目1 选择排序

01 认识复杂度、对数器、二分法 - 图1

  1. /**
  2. * 选择排序
  3. */
  4. public static void selectSort(int[] arr) {
  5. if (arr == null || arr.length < 2) {
  6. return;
  7. }
  8. /*
  9. * 0~N-1
  10. * 1~N-1
  11. * 2~N-1
  12. */
  13. for (int i = 0; i < arr.length - 1; i++) {
  14. int minIndex = i;
  15. // 找到最小值的数组下标,和第一个数做交换
  16. for (int j = i + 1; j < arr.length; j++) {
  17. minIndex = arr[minIndex] < arr[j] ? minIndex : j;
  18. }
  19. swap(arr, i, minIndex);
  20. }
  21. }
  22. /**
  23. * 交换数组两个下标的数
  24. */
  25. public static void swap(int[] arr, int i, int j) {
  26. int temp = arr[i];
  27. arr[i] = arr[j];
  28. arr[j] = temp;
  29. }

题目2 冒泡排序

01 认识复杂度、对数器、二分法 - 图2

  1. /**
  2. * 冒泡排序
  3. *
  4. * @param arr 数组
  5. */
  6. public static void bubbleSort(int[] arr) {
  7. if (arr == null || arr.length < 2) {
  8. return;
  9. }
  10. /*
  11. * 0~N-1
  12. * 0~N-2
  13. * 0~N-3
  14. * ...
  15. * 0~1
  16. * */
  17. for (int i = arr.length - 1; i > 0; i--) {
  18. for (int j = 0; j < i; j++) {
  19. if (arr[j] > arr[j + 1]) {
  20. swap(arr, j, j + 1);
  21. }
  22. }
  23. }
  24. }
  25. /**
  26. * 交换数组两个下标的数
  27. * 两个下标不指向同一块内存空间,可使用不增加变量的方式交换
  28. */
  29. public static void swap(int[] arr, int i, int j) {
  30. arr[i] = arr[i] ^ arr[j];
  31. arr[j] = arr[i] ^ arr[j];
  32. arr[i] = arr[i] ^ arr[j];
  33. }

题目3 插入排序

01 认识复杂度、对数器、二分法 - 图3

  1. /**
  2. * 插入排序
  3. *
  4. * @param arr 数组
  5. */
  6. public static void insertSort(int[] arr) {
  7. if (arr == null || arr.length < 2) {
  8. return;
  9. }
  10. for (int i = 1; i < arr.length; i++) {
  11. for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
  12. swap(arr, j, j - 1);
  13. }
  14. }
  15. }
  16. /**
  17. * 交换数组两个下标的数
  18. * 两个下标不指向同一块内存空间,可使用不增加变量的方式交换
  19. */
  20. public static void swap(int[] arr, int i, int j) {
  21. arr[i] = arr[i] ^ arr[j];
  22. arr[j] = arr[i] ^ arr[j];
  23. arr[i] = arr[i] ^ arr[j];
  24. }

题目4 希尔排序——改进的插入排序

01 认识复杂度、对数器、二分法 - 图4

  1. public static void shellSort(int[] arr) {
  2. if (arr == null || arr.length < 2) {
  3. return;
  4. }
  5. int h = 1;
  6. while (h <= arr.length / 3) {
  7. h = 3 * h + 1;
  8. }
  9. for (int gap = h; gap > 0; gap = (gap - 1) / 3) {
  10. for (int i = gap; i < arr.length; i++) {
  11. for (int j = i; j > gap - 1 && arr[j] < arr[j - gap]; j -= gap) {
  12. swap(arr, j, j - gap);
  13. }
  14. }
  15. }
  16. }

4 二分法应用

题目1:在一个有序数组中,找某个数是否存在

01 认识复杂度、对数器、二分法 - 图5

  1. /**
  2. * 有序数组,二分查找一个数是否存在,返回数的下标
  3. * @param arr 数组
  4. * @param num 数
  5. * @return 下标,不存在返回-1
  6. */
  7. public static int binarySearch(int[] arr, int num) {
  8. if (arr == null || arr.length < 1) {
  9. return -1;
  10. }
  11. int left = 0;
  12. int right = arr.length - 1;
  13. while (left <= right) {
  14. int mid = left + ((right - left) >> 1);
  15. if (arr[mid] == num) {
  16. return mid;
  17. } else if (arr[mid] < num) {
  18. left = mid + 1;
  19. } else {
  20. right = mid - 1;
  21. }
  22. }
  23. return -1;
  24. }


题目2:在一个有序数组中,找>=某个数最左侧的位置

01 认识复杂度、对数器、二分法 - 图6

  1. /**
  2. * 在一个有序数组中,找>=某个数最左侧的位置
  3. *
  4. * @param arr
  5. * @param num
  6. * @return
  7. */
  8. public static int binarySearchNearLeft(int[] arr, int num) {
  9. if (arr == null || arr.length < 1) {
  10. return -1;
  11. }
  12. int index = -1;
  13. int left = 0;
  14. int right = arr.length - 1;
  15. while (left <= right) {
  16. int mid = left + ((right - left) >> 1);
  17. if (arr[mid] >= num) {
  18. index = mid;
  19. right = mid - 1;
  20. } else {
  21. left = mid + 1;
  22. }
  23. }
  24. return index;
  25. }

题目3:局部最小值问题

01 认识复杂度、对数器、二分法 - 图7

  1. /**
  2. * 局部最小值问题
  3. *
  4. * @param arr 随机数组,满足相邻2个数不相等
  5. * @return 任意一个局部最小值
  6. */
  7. public static int binarySearchAwesome(int[] arr) {
  8. if (arr == null || arr.length < 1) {
  9. return -1;
  10. }
  11. if (arr.length == 1 || arr[0] < arr[1]) {
  12. return 0;
  13. }
  14. if (arr[arr.length - 1] < arr[arr.length - 2]) {
  15. return arr.length - 1;
  16. }
  17. int index = -1;
  18. int left = 0;
  19. int right = arr.length - 1;
  20. while (left <= right) {
  21. int mid = left + ((right - left) >> 1);
  22. if (arr[mid] < arr[mid - 1] && arr[mid] < arr[mid + 1]) {
  23. index = mid;
  24. break;
  25. } else if (arr[mid] > arr[mid - 1]) {
  26. right = mid;
  27. } else {
  28. left = mid;
  29. }
  30. }
  31. return index;
  32. }