update at 2020-10-01 17:34:22 by ehlxr

This commit is contained in:
2020-10-01 17:34:22 +08:00
parent 3a3240d4e5
commit 58684d9cdf
5 changed files with 238 additions and 95 deletions

View File

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

View File

@@ -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++) {

View File

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

View File

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

View File

@@ -0,0 +1,8 @@
package me.ehlxr.leetcode;
/**
* @author ehlxr
* @since 2020-10-01 16:40.
*/
public class ShellSort {
}