add 排序
This commit is contained in:
parent
8a1db63f81
commit
3b734ae0d0
71
3.排序算法/src/sort/exchange/HeapSort.java
Normal file
71
3.排序算法/src/sort/exchange/HeapSort.java
Normal file
@ -0,0 +1,71 @@
|
||||
package sort.exchange;
|
||||
|
||||
import util.ArrayUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 类功能简述:堆排序,不懂堆的建议看这个<a href="https://www.jianshu.com/p/6b526aa481b1">堆讲解</a>
|
||||
* 类功能详述: 基于升序排序.过程如下:
|
||||
* <p>
|
||||
* 1. 构建大顶堆(升序用大顶堆,降序用小顶堆) ,i=arr.lengh-1,n=arr.lengh
|
||||
* 2. 将arr[0]和arr[i]互换,
|
||||
* 3. i--
|
||||
* 4. 重新将arr 0到i 构建为大顶堆
|
||||
* 5. 重复2,3,4直到i=1
|
||||
* <p>
|
||||
* 构建大顶堆过程如下:
|
||||
* 从最后一个非叶子节点开始从下往上进行调整。
|
||||
* 将该节点的值调整为max(节点值,直接子节点值),注意如果产生了交换操作还要调整被交换节点,让其也是max(节点值,直接子节点值),直到被交换节点无子节点
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/31 19:02
|
||||
*/
|
||||
public class HeapSort {
|
||||
|
||||
|
||||
private static void sort(Integer[] arr) {
|
||||
int n = arr.length;
|
||||
//构建大顶堆
|
||||
for (int i = n / 2 - 1; i >= 0; i--) {
|
||||
adjustHeap(arr, i, n);
|
||||
}
|
||||
//排序
|
||||
for (int i = n - 1; i > 0; i--) {
|
||||
ArrayUtil.swap(arr, 0, arr[i]);
|
||||
adjustHeap(arr, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 调整堆
|
||||
*
|
||||
* @param arr 数组
|
||||
* @param index 调整index处的对结构
|
||||
* @param length 堆大小
|
||||
* @author fanxb
|
||||
* @date 2019/7/31 19:50
|
||||
*/
|
||||
private static void adjustHeap(Integer[] arr, int index, int length) {
|
||||
if (index >= length) {
|
||||
return;
|
||||
}
|
||||
int maxIndex = index;
|
||||
for (int i = 2 * index + 1; i < length - 1 && i <= 2 * index + 2; i++) {
|
||||
if (arr[maxIndex] < arr[i]) {
|
||||
maxIndex = i;
|
||||
}
|
||||
}
|
||||
//如果进行了交换,还要调整被交换节点
|
||||
if (maxIndex != index) {
|
||||
ArrayUtil.swap(arr, maxIndex, index);
|
||||
adjustHeap(arr, maxIndex, length);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[] arr = {1, 65, 32, 334, 12, 21, 65, 112, 444443};
|
||||
ShellSort.sort(arr);
|
||||
System.out.println(Arrays.toString(arr));
|
||||
}
|
||||
}
|
37
3.排序算法/src/sort/exchange/InsertSort.java
Normal file
37
3.排序算法/src/sort/exchange/InsertSort.java
Normal file
@ -0,0 +1,37 @@
|
||||
package sort.exchange;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 类功能简述:插入排序
|
||||
* 类功能详述:按照升序讲解
|
||||
* 将数组分为有序部分和无序部分,最开始的有序部分为空,无序部分为整个数组
|
||||
* 1. 取无序部分第一个值temp
|
||||
* 2. 和有序部分从后向前比较,如果有序部分的值大于temp,则该值向后移动一位,继续比较;如果有序部分值小于等于temp,
|
||||
* 将temp放到这个值后一位(前面的移动就是为了给temp留位子),a成功插入到有序部分中。
|
||||
* 3. 重复1和2
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/31 16:46
|
||||
*/
|
||||
public class InsertSort {
|
||||
|
||||
public static void sort(Integer[] arr) {
|
||||
for (int i = 0, length = arr.length; i < length; i++) {
|
||||
//有序部分从后向前比较
|
||||
int j = i, temp = arr[i];
|
||||
//如果arr[j-1]<=temp,说明arr[j]需为temp,否则将arr[j-1]向后移动一位
|
||||
for (; j > 0 && temp < arr[j - 1]; j--) {
|
||||
arr[j] = arr[j - 1];
|
||||
}
|
||||
arr[j] = temp;
|
||||
System.out.println("当前数组状态为:"+Arrays.toString(arr));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[] arr = {1, 65, 32, 12, 21};
|
||||
InsertSort.sort(arr);
|
||||
System.out.println(Arrays.toString(arr));
|
||||
}
|
||||
}
|
68
3.排序算法/src/sort/exchange/MergeSort.java
Normal file
68
3.排序算法/src/sort/exchange/MergeSort.java
Normal file
@ -0,0 +1,68 @@
|
||||
package sort.exchange;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 类功能简述:归并排序
|
||||
* 类功能详述:
|
||||
* <p>
|
||||
* 定义:<a href="https://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F">参见维基百科</a>
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/8/5 16:25
|
||||
*/
|
||||
public class MergeSort {
|
||||
|
||||
public static void mergeSort(Integer[] arr, int start, int end) {
|
||||
if (start >= end) {
|
||||
return;
|
||||
}
|
||||
int half = (start + end) / 2;
|
||||
mergeSort(arr, start, half);
|
||||
mergeSort(arr, half + 1, end);
|
||||
merge(arr, start, half, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* @param arr arr
|
||||
* @author fanxb
|
||||
* @date 2019/8/5 17:36
|
||||
*/
|
||||
public static void merge(Integer[] arr, int start, int half, int end) {
|
||||
ArrayList<Integer> tempList = new ArrayList<>();
|
||||
int i = start, j = half + 1;
|
||||
// 循环比较,将较小的放到tempList中
|
||||
while (i <= half && j <= end) {
|
||||
if (arr[i] <= arr[j]) {
|
||||
tempList.add(arr[i]);
|
||||
i++;
|
||||
} else {
|
||||
tempList.add(arr[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (i > half) {
|
||||
//说明第一个数组已经完了,将第二个数组的剩余部分放到tempList中
|
||||
while (j <= end) {
|
||||
tempList.add(arr[j]);
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
//说明第二个数组卖完了,将第二个数组剩余部分放到tempList中
|
||||
while (j <= half) {
|
||||
//说明第二个数组处理完了
|
||||
tempList.add(arr[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[] arr = {4, 3, 1, 2, 5, 4, 2, 54};
|
||||
mergeSort(arr, 0, arr.length);
|
||||
}
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
package sort.exchange;
|
||||
|
||||
import util.ArrayUtil;
|
||||
import util.NumberUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 类功能简述:快速排序
|
||||
* 类功能详述:使用了分治的思想,先取一个数,然后让这个数的左边都是小于等于它的,右边都大于等于它,然后左边右边分布做同样的处理,
|
||||
* 类功能详述:
|
||||
* 1.使用了分治的思想,先取一个数作为基数(一般选第一个数),然后将这个数移动到一个合适的位置使左边的都比它小,右边的都比他大
|
||||
* 2.递归处理这个数左边的数和右边的数,直到所有的数都有序。
|
||||
* 直到所有的数都有序
|
||||
*
|
||||
* @author fanxb
|
||||
@ -19,33 +20,33 @@ public class QuickSort {
|
||||
if (start >= end) {
|
||||
return;
|
||||
}
|
||||
int baseIndex = NumberUtil.getRandom(start, end);
|
||||
int base = arr[baseIndex], i = start, j = end;
|
||||
int base = arr[start], i = start, j = end;
|
||||
while (i < j) {
|
||||
//在右边找一个比基数小的数,直到i,j相等
|
||||
while (arr[j] >= base && j > i) {
|
||||
j--;
|
||||
}
|
||||
while (arr[i] <= base && i < j) {
|
||||
|
||||
//在左边找一个比基数大的数,直到i,j相等
|
||||
while (arr[i] <= base && j > i) {
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
//如果ij不相等,交换其值
|
||||
if (i < j) {
|
||||
ArrayUtil.swap(arr, i++, j--);
|
||||
System.out.println(Arrays.toString(arr));
|
||||
}
|
||||
}
|
||||
boolean isSwap = (baseIndex > j && arr[baseIndex] < arr[j]) || (baseIndex < j && arr[baseIndex] > arr[j]);
|
||||
if (isSwap) {
|
||||
ArrayUtil.swap(arr, baseIndex, i);
|
||||
//此时i等于j,交换基数和i/j,使左边的数小于等于基数,右边的数大于等于基数
|
||||
if (start != i) {
|
||||
ArrayUtil.swap(arr, start, i);
|
||||
}
|
||||
System.out.println(Arrays.toString(arr));
|
||||
deal(arr, start, i - 1);
|
||||
deal(arr, j + 1, end);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[] arr = {1, 43, 2, 3, 4, 5, 6, 7, 5, 6, 555, 12, 31, 5, 5};
|
||||
Integer[] arr = {1, 43, 2, 7, 5, 6, 555, 200, 21};
|
||||
deal(arr, 0, arr.length - 1);
|
||||
System.out.println("结果" + Arrays.toString(arr));
|
||||
}
|
||||
}
|
||||
|
45
3.排序算法/src/sort/exchange/ShellSort.java
Normal file
45
3.排序算法/src/sort/exchange/ShellSort.java
Normal file
@ -0,0 +1,45 @@
|
||||
package sort.exchange;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 类功能简述:希尔排序
|
||||
* 类功能详述:以升序为例
|
||||
* 希尔排序也是插入排序的一种,是对上面的直接插入排序的一种改进。因为直接插入排序在数组大致有序时效率较高,如果数组完全逆序的情况
|
||||
* 下效率就很慢了,因为一次只能移动一个位置,完全逆序的情况下每次插入都会移动非常多的次数,效率很慢。希尔排序的目的就是一次能够移动多个
|
||||
* 位置,减少移动次数。详细过程如下:
|
||||
* 1. 取一个小于数组长度n的整数n1,将所有间隔为n1的数分成一组,对各组进行直接插入排序.然后n=n1;
|
||||
* 2. 重复上述操纵,直到n1=1进行一次完整的插入排序后结束。
|
||||
* <p>
|
||||
* 总体思想是先一次移动多个位置,让数组整体大致有序,这样当n=1时再直接插入排序速度会快很多。
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/31 17:17
|
||||
*/
|
||||
public class ShellSort {
|
||||
|
||||
public static void sort(Integer[] arr) {
|
||||
int n1 = arr.length / 2;
|
||||
// 也可将do/while替换成尾递归
|
||||
do {
|
||||
//共n1组数据需要进行直接插入排序
|
||||
for (int start = 0; start < n1; start++) {
|
||||
//对一组执行插入排序,第一个数为arr[start],增量为n1
|
||||
for (int i = start; i < arr.length; i += n1) {
|
||||
int j = i, temp = arr[i];
|
||||
for (; j > start && temp < arr[j - n1]; j -= n1) {
|
||||
arr[j] = arr[j - n1];
|
||||
}
|
||||
arr[j] = temp;
|
||||
}
|
||||
}
|
||||
n1 /= 2;
|
||||
} while (n1 > 0);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[] arr = {1, 65, 32, 12, 21};
|
||||
ShellSort.sort(arr);
|
||||
System.out.println(Arrays.toString(arr));
|
||||
}
|
||||
}
|
36
3.排序算法/src/sort/exchange/SimpleSelectSort.java
Normal file
36
3.排序算法/src/sort/exchange/SimpleSelectSort.java
Normal file
@ -0,0 +1,36 @@
|
||||
package sort.exchange;
|
||||
|
||||
import util.ArrayUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 类功能简述:简单选择排序
|
||||
* 类功能详述:以升序为例
|
||||
* <p>
|
||||
* 简单选择排序顾名思义,每次从无序部分选出一个最大的数,和无序部分的最后一个值交换,重复n-1次后所有的值都变成有序状态
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/31 17:49
|
||||
*/
|
||||
public class SimpleSelectSort {
|
||||
|
||||
public static void sort(Integer[] arr) {
|
||||
int length = arr.length;
|
||||
for (int i = 0; i < length - 1; i++) {
|
||||
int maxIndex = 0;
|
||||
for (int j = 1; j < length - i; j++) {
|
||||
if (arr[j] > arr[maxIndex]) {
|
||||
maxIndex = j;
|
||||
}
|
||||
}
|
||||
ArrayUtil.swap(arr, maxIndex, length - i);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[] arr = {1, 65, 32, 12, 21};
|
||||
ShellSort.sort(arr);
|
||||
System.out.println(Arrays.toString(arr));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user