package Case.case01;
// 2022年8月6日 花费将近3小时完成10个排序
import java.util.Arrays;
/**
* 10大排序
* 1.冒泡排序
* 2.选择排序
* 3.插入排序
* 4.希尔排序
* 5.快速排序
* 6.归并排序
* 7.基数排序
* 8.计数排序
* 9.桶排序
* 10.堆排序
*/
public class Sort {
//交换方法
public void swap(int[] arr,int i,int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//冒泡排序
public void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length;i++) {
boolean flag = true;
for (int j = 0; j < arr.length-1-i;j++) {
if (arr[j] > arr[j+1]) {
swap(arr, j, j+1);
flag = false;
}
}
if (flag) {
break;
}
}
}
//选择排序
public void chooseSort(int[] arr) {
for (int i = 0; i < arr.length-1;i++) {
//假設下標i為最小值
int minIndex = i;
int minVal = arr[i];
//for循環找到最小值
for (int j = i+1; j < arr.length;j++) {
if (minVal > arr[j]) {
minVal = arr[j];
i = j;
}
}
//找到了最小值下标
if (minIndex != i) {
//交换
swap(arr, minIndex, i);
}
}
}
//插入排序
public void insertSort(int[] arr) {
//假设第一个元素是有序的,后面的元素是无序的
for (int i = 1; i < arr.length;i++) {
//记录待插入的前一个下标和值
int insertIndex = i-1;
int insertVal = arr[i];
//不停的向向前寻找位置
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex+1] = arr[insertIndex];
insertIndex--;
}
//找到了待插入的位置
arr[insertIndex+1] = insertVal;
}
}
//希尔排序
public void shellSort(int[] arr) {
//插入排序的优化版,先分组 + 再插入
//准备变量存放特定意义的值
int length = arr.length; //存放arr数组的大小
int index = 1; //位移量
int carry = length >> index; //进位
//开始分组
while (carry > 0) {
//for循环以carry为步长
for (int k = carry; k < length;k++) {
//记住k是要插入的值和前面的下标
int insertVal = arr[k];
int insertIndex = k - carry;
//while循环寻找代插入的索引
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex+carry] = arr[insertIndex];
insertIndex -= carry;
}
//找到了insertIndex+carry
arr[insertIndex+carry] = insertVal;
}
index++;
carry = length >> index;
}
}
//快速排序
public int quickSort(int[] arr,int left,int right) {
//选择基准点,以left为基准点,开始填坑法
int baseVal = arr[left];
int l = left; //左指针
int r = right; //右指针
int index = left; //记录坑位
while (l < r) {
//从右边选择一个小于等于baseVal的数填入index索引处
while (l < r && arr[r] > baseVal) {
r--;
}
//找到了坑位
arr[index] = arr[r]; //填坑
index = r; //重新赋值坑位
//再从左边寻找一个大于baseVal的数填入index索引处
while (l < r && arr[l] <= baseVal) {
l++;
}
//找到了坑位
arr[index] = arr[l]; //填坑
index = l; //重新赋值坑位
}
//最后l = r 将基准点放入l 或者 r 下标中
arr[l] = baseVal;
return r;
}
//快速排序递归调用
public void quickSortRecursion(int[] arr,int left,int right) {
if (left < right)
{
int i = quickSort(arr, left, right);
//向左递归排序
quickSortRecursion(arr, left, i-1);
//向右递归排序
quickSortRecursion(arr, i+1, right);
}
}
//归并排序
//拷贝合并数组
public void merge(int[] arr,int left,int mid,int right,int[] temp) {
//记录两边数组的最左下标
int i = left;
int j = mid+1;
int tempIndex = 0; //temp数组的下标
//1.拷贝数据到temp数组中
while (i <= mid && j <= right) {
//拷贝
//判断
if (arr[i] <= arr[j]) {
//先放入i数组中的值
temp[tempIndex] = arr[i];
tempIndex += 1;
i += 1;
}else {
//放入j数组中的值
temp[tempIndex] = arr[j];
tempIndex += 1;
j += 1;
}
}
//2.将剩下的数组数据依次拷贝到temp数组中
while (i <= mid) {
//拷贝i中的数据
temp[tempIndex] = arr[i];
tempIndex += 1;
i += 1;
}
while (j <= right) {
//拷贝j数组中的值
temp[tempIndex] = arr[j];
tempIndex += 1;
j += 1;
}
//3.将temp中的数据拷贝回arr中
for (int k = left,index = 0; k <= right;k++,index++) {
arr[k] = temp[index];
}
}
//归并排序 分解
public void decompose(int[] arr,int left,int right,int[] temp) {
if (left < right)
{
int mid = left + ((right - left) >> 1);
//向左分解
//System.out.println("l = " + left+" mid = " + mid+" r = " + right);
decompose(arr, left, mid,temp);
//向右分解
decompose(arr, mid+1, right,temp);
//合并merge
merge(arr, left, mid, right, temp);
}
}
//基数排序
public void radixSort(int[] arr) {
//准备10个桶的二维数组
int[][] bucket = new int[10][arr.length];
//准备1个一维数组10
int[] bucketCount = new int[10];
//找到arr数组中最长的数的长度
int length = arr[0];
for (int i = 1; i < arr.length;i++) {
if (length < arr[i]) {
length = arr[i];
}
}
length = ("" + length).length(); //运行次数
//控制运行次数
for (int k = 1,n = 1;k <= length;k++,n *= 10) {
//存储数据到二维数组中
for (int i = 0; i < arr.length;i++) {
int bucketCountIndex = arr[i] / n % 10;
bucket[bucketCountIndex][bucketCount[bucketCountIndex]] = arr[i];
bucketCount[bucketCountIndex]++;
}
//依次取出数据
int index = 0;
for (int i = 0; i < bucketCount.length;i++) {
if (bucketCount[i] > 0) {
int tempI = 0;
while (tempI < bucketCount[i]) {
arr[index] = bucket[i][tempI];
tempI++;
index++;
}
}
bucketCount[i] = 0; //置于0便于下次使用
}
}
}
//计数排序
public void countSort(int[] arr) {
//获取arr中的最大值
int maxVal = arr[0];
for (int k = 1; k < arr.length; k++) {
if (maxVal < arr[k]) {
maxVal = arr[k];
}
}
//创建计数数组
int[] countArr = new int[maxVal+1];
int temp = 0;
//开始计数
for (int k = 0; k < arr.length; k++) {
temp = arr[k];
countArr[temp]++;
}
//开始遍历
int index = 0;
for (int k = 0; k < countArr.length; k++) {
while (countArr[k] > 0) {
arr[index] = k;
countArr[k]--;
index++;
}
}
}
//桶排序
public void bucketSort(int[] arr) {
//只排序0-99的数 10 * 10
int[][] bucket = new int[10][arr.length];
//int[] bucketCount用于存放下标
int[] bucketCount = new int[10];
//i j 表示bucket存放的位置
int i = 0;
//遍历arr数组 将arr中的数放入桶中
for (int k = 0; k < arr.length;k++) {
i = arr[k] / 10 % 10;
bucket[i][bucketCount[i]++] = arr[k];
}
//在桶中排序
int index = 0; //arr的索引
int temp = 0;
for (int k = 0; k <bucketCount.length; k++) {
if (bucketCount[k] > 0) {
int size = bucketCount[k];
//假设第一个数是最小的
for (int j = 0; j < size;j++) {
int minVal = bucket[k][j];
for (int l = j+1; l < size;l++) {
if (minVal > bucket[k][l]) {
temp = minVal;
minVal = bucket[k][l];
bucket[k][l] = temp;
}
}
//找到了最小值
arr[index] = minVal;
index += 1;
}
}
}
}
//堆排序 - > 大顶堆排序
public void bigHeap(int[] arr,int i,int length) {
//记录节点值
int temp = arr[i];
//向左循环遍历,找出节点中的最大值
for (int n = i * 2 + 1; n < length; n = n * 2 + 1) {
if (n+1 < length && arr[n] < arr[n+1]) {
n++;
}
if (arr[n] > temp) {
arr[i] = arr[n];
i = n;
}else {
break;
}
}
arr[i] = temp;
}
//堆排序
public void headSort(int[] arr,int i,int length) {
//循环 大顶堆排序
int size = length-1;
while (size > 0) {
for (int k = i; k >= 0; k = ( k-1) >> 1) {
bigHeap(arr,k,size+1);
}
//交换
swap(arr, 0, size);
size--;
}
}
public static void main(String[] args) {
int[] arr = {5,8,4,2,3,44};
System.out.println("排序前:" + Arrays.toString(arr));
Sort sort = new Sort();
sort.headSort(arr,arr.length/2-1,arr.length);
System.out.println("排序后:" + Arrays.toString(arr));
}
}