update at 2020-10-01 17:34:22 by ehlxr
parent
3a3240d4e5
commit
58684d9cdf
|
@ -0,0 +1,50 @@
|
|||
package me.ehlxr.leetcode;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 冒泡排序
|
||||
* <p>
|
||||
* 它重复访问要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
|
||||
* 访问数列的工作是重复地进行直到没有再需要交换的数据,也就是说该数列已经排序完成
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2020-10-01 16:40.
|
||||
*/
|
||||
public class BubbleSort {
|
||||
|
||||
/**
|
||||
* 冒泡排序算法的算法过程如下:
|
||||
* ①. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
|
||||
* ②. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
|
||||
* ③. 针对所有的元素重复以上的步骤,除了最后一个。
|
||||
* ④. 持续每次对越来越少的元素重复上面的步骤①~③,直到没有任何一对数字需要比较。
|
||||
*/
|
||||
public static void sort(int[] arr) {
|
||||
//外层:需要 length-1 次循环比较
|
||||
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]) {
|
||||
swap(arr, j, j + 1);
|
||||
}
|
||||
}
|
||||
System.out.println("Sorting: " + Arrays.toString(arr));
|
||||
}
|
||||
}
|
||||
|
||||
public static void swap(int[] arr, int i, int j) {
|
||||
// arr[i] = arr[i] + arr[j];
|
||||
// arr[j] = arr[i] - arr[j];
|
||||
// arr[i] = arr[i] - arr[j];
|
||||
|
||||
int tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
sort(new int[]{4, 9, 1, 6, 8, 2});
|
||||
}
|
||||
}
|
|
@ -3,7 +3,9 @@ package me.ehlxr.leetcode;
|
|||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 直接插入排序的基本思想是:
|
||||
* 插入排序
|
||||
*
|
||||
* 基本思想是:
|
||||
* 将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,
|
||||
* 则交换,直到全部元素都比较过为止。
|
||||
*
|
||||
|
@ -14,11 +16,11 @@ public class InsertSort {
|
|||
|
||||
/**
|
||||
* ①. 从第一个元素开始,该元素可以认为已经被排序
|
||||
* ②. 取出下一个元素,在已经排序的元素序列中从后向前扫描
|
||||
* ②. 取出下一个元素(新元素),在已经排序的元素序列中从后向前扫描
|
||||
* ③. 如果该元素(已排序)大于新元素,将该元素移到下一位置
|
||||
* ④. 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置
|
||||
* ⑤. 将新元素插入到该位置后
|
||||
* ⑥. 重复步骤②~⑤
|
||||
* ⑥. 重复步骤 ②~⑤
|
||||
*/
|
||||
public static void sort(int[] arr) {
|
||||
for (int i = 1; i < arr.length; i++) {
|
||||
|
|
|
@ -2,91 +2,40 @@ package me.ehlxr.leetcode;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 快速排序
|
||||
* <p>
|
||||
* 快速排序(Quicksort)是对冒泡排序的一种改进,借用了分治的思想,
|
||||
* 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,
|
||||
* 其中一部分的所有数据都比另外一部分的所有数据都要小,
|
||||
* 然后再按此方法对这两部分数据分别进行快速排序,
|
||||
* 整个排序过程可以递归进行,以此达到整个数据变成有序序列。
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2020-10-01 16:40.
|
||||
*/
|
||||
public class QuickSort {
|
||||
/**
|
||||
* 快速排序(左右指针法)
|
||||
*
|
||||
* @param arr 待排序数组
|
||||
* @param low 左边界
|
||||
* @param high 右边界
|
||||
*/
|
||||
public static void sort(int[] arr, int low, int high) {
|
||||
if (arr == null || arr.length <= 0) {
|
||||
return;
|
||||
}
|
||||
if (low >= high) {
|
||||
return;
|
||||
}
|
||||
|
||||
int left = low;
|
||||
int right = high;
|
||||
|
||||
int key = arr[left];
|
||||
|
||||
while (left < right) {
|
||||
while (left < right && arr[right] >= key) {
|
||||
right--;
|
||||
}
|
||||
while (left < right && arr[left] <= key) {
|
||||
left++;
|
||||
}
|
||||
if (left < right) {
|
||||
swap(arr, left, right);
|
||||
}
|
||||
}
|
||||
swap(arr, low, left);
|
||||
System.out.println("Sorting: " + Arrays.toString(arr));
|
||||
sort(arr, low, left - 1);
|
||||
sort(arr, left + 1, high);
|
||||
}
|
||||
|
||||
public static void swap(int[] arr, int low, int high) {
|
||||
int tmp = arr[low];
|
||||
arr[low] = arr[high];
|
||||
arr[high] = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速排序(挖坑法递归)
|
||||
*
|
||||
* @param arr 待排序数组
|
||||
* @param low 左边界
|
||||
* @param high 右边界
|
||||
*/
|
||||
public static void sort2(int[] arr, int low, int high) {
|
||||
if (arr == null || arr.length <= 0) {
|
||||
return;
|
||||
}
|
||||
if (low >= high) {
|
||||
return;
|
||||
}
|
||||
|
||||
int left = low;
|
||||
int right = high;
|
||||
int temp = arr[left]; //挖坑1:保存基准的值
|
||||
|
||||
while (left < right) {
|
||||
while (left < right && arr[right] >= temp) {
|
||||
right--;
|
||||
}
|
||||
arr[left] = arr[right]; //坑2:从后向前找到比基准小的元素,插入到基准位置坑1中
|
||||
while (left < right && arr[left] <= temp) {
|
||||
left++;
|
||||
}
|
||||
arr[right] = arr[left]; //坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中
|
||||
}
|
||||
arr[left] = temp; //基准值填补到坑3中,准备分治递归快排
|
||||
System.out.println("Sorting: " + Arrays.toString(arr));
|
||||
sort2(arr, low, left - 1);
|
||||
sort2(arr, left + 1, high);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arrs = {2, 4, 7, 5};
|
||||
sort3(arrs, 0, arrs.length - 1);
|
||||
int[] arr = {4, 9, 1, 6, 8, 2};
|
||||
sort(arr, 0, arr.length - 1);
|
||||
}
|
||||
|
||||
public static void sort3(int[] arr, int l, int r) {
|
||||
/**
|
||||
* 快速排序使用分治策略来把一个序列(list)分为两个子序列(sub-lists)。
|
||||
* 步骤为:
|
||||
* ①. 从数列中挑出一个元素,称为 "基准"(pivot)。
|
||||
* ②. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。
|
||||
* 在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
|
||||
* ③. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
|
||||
* <p>
|
||||
* 递归到最底部时,数列的大小是零或一,也就是已经排序好了。
|
||||
* 这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
|
||||
*
|
||||
* @param arr 待排序数组
|
||||
* @param l 左边界
|
||||
* @param r 右边界
|
||||
*/
|
||||
public static void sort(int[] arr, int l, int r) {
|
||||
if (l >= r) {
|
||||
return;
|
||||
}
|
||||
|
@ -95,25 +44,106 @@ public class QuickSort {
|
|||
return;
|
||||
}
|
||||
|
||||
int i = l, j = r, x = l;
|
||||
int k = arr[x];
|
||||
int i = l, j = r,
|
||||
// 一般选择数组左边界作为基准
|
||||
k = l;
|
||||
int p = arr[k];
|
||||
|
||||
while (l < r) {
|
||||
while (l < r && arr[r] >= k) {
|
||||
// 首先循环递减右边界,直到找到小于基准的元素,相互交换
|
||||
while (l < r && arr[r] >= p) {
|
||||
r--;
|
||||
}
|
||||
arr[x] = arr[r];
|
||||
x = r;
|
||||
arr[k] = arr[r];
|
||||
k = r;
|
||||
|
||||
while (l < r && arr[l] <= k) {
|
||||
// 其次循环递增左边界,直到找到大于基准的元素,相互交换
|
||||
while (l < r && arr[l] <= p) {
|
||||
l++;
|
||||
}
|
||||
arr[x] = arr[l];
|
||||
x = l;
|
||||
arr[k] = arr[l];
|
||||
k = l;
|
||||
|
||||
// 循环以上步骤,直到 l 和 r 相遇
|
||||
}
|
||||
arr[x] = k;
|
||||
arr[k] = p;
|
||||
System.out.println("Sorting: " + Arrays.toString(arr));
|
||||
|
||||
sort3(arr, i, x - 1);
|
||||
sort3(arr, x + 1, j);
|
||||
sort(arr, i, k - 1);
|
||||
sort(arr, k + 1, j);
|
||||
}
|
||||
|
||||
/*
|
||||
* 左右指针法
|
||||
*/
|
||||
// public static void sort(int[] arr, int low, int high) {
|
||||
// if (arr == null || arr.length <= 0) {
|
||||
// return;
|
||||
// }
|
||||
// if (low >= high) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int left = low;
|
||||
// int right = high;
|
||||
//
|
||||
// int key = arr[left];
|
||||
//
|
||||
// while (left < right) {
|
||||
// while (left < right && arr[right] >= key) {
|
||||
// right--;
|
||||
// }
|
||||
// while (left < right && arr[left] <= key) {
|
||||
// left++;
|
||||
// }
|
||||
// if (left < right) {
|
||||
// swap(arr, left, right);
|
||||
// }
|
||||
// }
|
||||
// swap(arr, low, left);
|
||||
// System.out.println("Sorting: " + Arrays.toString(arr));
|
||||
// sort(arr, low, left - 1);
|
||||
// sort(arr, left + 1, high);
|
||||
// }
|
||||
|
||||
/*
|
||||
* 挖坑法递归
|
||||
*/
|
||||
// public static void sort2(int[] arr, int low, int high) {
|
||||
// if (arr == null || arr.length <= 0) {
|
||||
// return;
|
||||
// }
|
||||
// if (low >= high) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int left = low;
|
||||
// int right = high;
|
||||
// // 挖坑1:保存基准的值
|
||||
// int temp = arr[left];
|
||||
//
|
||||
// while (left < right) {
|
||||
// while (left < right && arr[right] >= temp) {
|
||||
// right--;
|
||||
// }
|
||||
// //坑2:从后向前找到比基准小的元素,插入到基准位置坑1中
|
||||
// arr[left] = arr[right];
|
||||
// while (left < right && arr[left] <= temp) {
|
||||
// left++;
|
||||
// }
|
||||
// //坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中
|
||||
// arr[right] = arr[left];
|
||||
// }
|
||||
// //基准值填补到坑3中,准备分治递归快排
|
||||
// arr[left] = temp;
|
||||
// System.out.println("Sorting: " + Arrays.toString(arr));
|
||||
// sort2(arr, low, left - 1);
|
||||
// sort2(arr, left + 1, high);
|
||||
// }
|
||||
|
||||
public static void swap(int[] arr, int low, int high) {
|
||||
int tmp = arr[low];
|
||||
arr[low] = arr[high];
|
||||
arr[high] = tmp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package me.ehlxr.leetcode;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 选择排序
|
||||
* <p>
|
||||
* 在未排序序列中找到最小(大)元素,存放到未排序序列的起始位置
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2020-10-01 16:55.
|
||||
*/
|
||||
public class SelectSort {
|
||||
|
||||
/**
|
||||
* ①. 从待排序序列中,找到关键字最小的元素;
|
||||
* ②. 如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
|
||||
* ③. 从余下的 N - 1 个元素中,找出关键字最小的元素,重复①、②步,直到排序结束。
|
||||
*/
|
||||
public static void sort(int[] arr) {
|
||||
for (int i = 0; i < arr.length - 1; i++) {
|
||||
// for (int j = i + 1; j < arr.length; j++) {
|
||||
// if (arr[i] > arr[j]) {
|
||||
// swap(arr, i, j);
|
||||
// }
|
||||
// }
|
||||
int min = i;
|
||||
for (int j = i + 1; j < arr.length; j++) {
|
||||
if (arr[min] > arr[j]) {
|
||||
min = j;
|
||||
}
|
||||
}
|
||||
if (min != i) {
|
||||
swap(arr, min, i);
|
||||
}
|
||||
System.out.println("Sorting: " + Arrays.toString(arr));
|
||||
}
|
||||
}
|
||||
|
||||
public static void swap(int[] arr, int i, int j) {
|
||||
// arr[i] = arr[i] + arr[j];
|
||||
// arr[j] = arr[i] - arr[j];
|
||||
// arr[i] = arr[i] - arr[j];
|
||||
|
||||
int tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
sort(new int[]{4, 9, 1, 6, 8, 2});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package me.ehlxr.leetcode;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2020-10-01 16:40.
|
||||
*/
|
||||
public class ShellSort {
|
||||
}
|
Loading…
Reference in New Issue