add 排序

This commit is contained in:
fanxb 2019-08-05 17:53:57 +08:00
parent 8a1db63f81
commit 3b734ae0d0
6 changed files with 271 additions and 13 deletions

View 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. 重复234直到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));
}
}

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

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

View File

@ -1,13 +1,14 @@
package sort.exchange; package sort.exchange;
import util.ArrayUtil; import util.ArrayUtil;
import util.NumberUtil;
import java.util.Arrays; import java.util.Arrays;
/** /**
* 类功能简述快速排序 * 类功能简述快速排序
* 类功能详述使用了分治的思想先取一个数然后让这个数的左边都是小于等于它的右边都大于等于它然后左边右边分布做同样的处理 * 类功能详述
* 1.使用了分治的思想先取一个数作为基数一般选第一个数然后将这个数移动到一个合适的位置使左边的都比它小右边的都比他大
* 2.递归处理这个数左边的数和右边的数直到所有的数都有序
* 直到所有的数都有序 * 直到所有的数都有序
* *
* @author fanxb * @author fanxb
@ -19,33 +20,33 @@ public class QuickSort {
if (start >= end) { if (start >= end) {
return; return;
} }
int baseIndex = NumberUtil.getRandom(start, end); int base = arr[start], i = start, j = end;
int base = arr[baseIndex], i = start, j = end;
while (i < j) { while (i < j) {
//在右边找一个比基数小的数,直到i,j相等
while (arr[j] >= base && j > i) { while (arr[j] >= base && j > i) {
j--; j--;
} }
while (arr[i] <= base && i < j) {
//在左边找一个比基数大的数,直到i,j相等
while (arr[i] <= base && j > i) {
i++; i++;
} }
//如果ij不相等交换其值
if (i < j) { if (i < j) {
ArrayUtil.swap(arr, 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]); //此时i等于j交换基数和i/j,使左边的数小于等于基数右边的数大于等于基数
if (isSwap) { if (start != i) {
ArrayUtil.swap(arr, baseIndex, i); ArrayUtil.swap(arr, start, i);
} }
System.out.println(Arrays.toString(arr));
deal(arr, start, i - 1); deal(arr, start, i - 1);
deal(arr, j + 1, end); deal(arr, j + 1, end);
} }
public static void main(String[] args) { 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); deal(arr, 0, arr.length - 1);
System.out.println("结果" + Arrays.toString(arr));
} }
} }

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

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