package Sort;
import java.util.Arrays;
//快速排序
public class QuickSort {
public static void main(String[] args) {
int[] arr = {
-9,78,0,23,-567,70};
quick(arr,0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
//最左边和最右边的索引
public static void quick(int[] arr,int left,int right){
int l =left;
int r = right;
int pivot = arr[(r+l)/2];//中轴值
int temp = 0;
//while循环的目的是把比pivot小的值放在左边
while (l<r){
//在pivot左边一直找
while (arr[l]<pivot){
l++;//如果出现比中轴值大的情况,下标就会卡在这里
}
while (arr[r]>pivot){
r--;
}
if (l>=r){
//如果此条件成立,说明pivot左边的值全是小于等于、右边全是大于等于pivot的值
break;
}
//交换
temp=arr[l];
arr[l]=arr[r];
arr[r]=temp;
//可能中间会有若干个值相同的元素,需要--前移一次再做判断,否则会死循环
if (arr[l]==pivot){
r--;
}
if (arr[r]==pivot){
l++;
}
}
//如果l==r,必须r--,l++,否则会出现栈溢出
if (l==r){
r--;
l++;
}
//左递归
if (left<r){
quick(arr,left,r);
}
//右递归
if (right>l){
quick(arr,l,right);
}
}
}
代码实现
package Sort;
import java.util.Arrays;
//归并排序
public class MergeSort {
public static void main(String[] args) {
int[] arr = {
8, 4, 5, 7, 1, 3, 6, 2};
int[] temp = new int[arr.length];
mergeSort1(arr,0,arr.length - 1,temp);
System.out.println(Arrays.toString(arr));
}
//分+合方法
public static void mergeSort1(int[] arr, int left, int right, int[] temp) {
if (left < right) {
//分到二者重合,即只剩一个数
int mid = (left + right)/2;
//向左递归进行分解
mergeSort1(arr, left, mid, temp);
//右递归
mergeSort1(arr, mid + 1, right, temp);
//到合并
merge(arr, left, mid, right, temp);
}
}
//合并的方法
/**
* @param arr 原始数组
* @param left 初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;
int t = 0;//临时数组的当前索引
//先把左右两边这2个有序数组按规则填充到temp数组中,直到一方处理完毕
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t+=1;
i++;
} else {
temp[t] = arr[j];
t+=1;
j++;
}
}
//另一方将剩余的元素全部填入temp中
while (i<=mid){
temp[t]=arr[i];
t+=1;
i++;
}
while (j<=right){
temp[t]=arr[j];
t+=1;
j++;
}
//将temp数组中的元素拷贝到arr
//注:不是每次都拷贝所有
t=0;
int tempLeft=left;
while (tempLeft<=right){
//第一次合并tempLeft=0,right=1
arr[tempLeft]=temp[t];
t++;
tempLeft++;
}
}
}
package Sort;
import java.util.Arrays;
//桶排序
public class RadixSort {
public static void main(String[] args) {
int[] arr = {
53, 3, 542, 748, 14, 214};
radix(arr);
System.out.println(Arrays.toString(arr));
}
public static void radix(int[] arr) {
//得到数组中最大数的位数
int max = arr[0];
for (int m = 1; m < arr.length; m++) {
if (arr[m] > max) {
max = arr[m];
}
}
int maxLength = (max + "").length();
//定义一个二维数组,表示10个桶,每个桶代表一个一维数组
//为了防止数组的数据溢出,每个桶的大小定义为arr.length
//因此,桶排序是空间换时间的经典算法
int[][] bucket = new int[10][arr.length];
//为了记录每个桶中实际存放了多少数据,定义一个一维数组
int[] eleCounts = new int[10];
for (int n = 0, o = 1; n < maxLength; n++,o*=10) {
for (int j = 0; j < arr.length; j++) {
int digitEle = arr[j] / o % 10;
//放入对应的桶
bucket[digitEle][eleCounts[digitEle]] = arr[j];
//对应桶数据个数+1
eleCounts[digitEle]++;
}
//按照桶的顺序把数据取回来
int index = 0;
//外层遍历桶、内层遍历桶里的数据
for (int i = 0; i < eleCounts.length; i++) {
//就是10
if (eleCounts[i] != 0) {
for (int j = 0; j < eleCounts[i]; j++) {
arr[index] = bucket[i][j];
index++;
}
}
//重要:一轮结束后,要将计数数组中对应的数据数量重置
eleCounts[i] = 0;
}
}
// //第一轮(针对个位)
// //定义一个二维数组,表示10个桶,每个桶代表一个一维数组
// //为了防止数组的数据溢出,每个桶的大小定义为arr.length
// //因此,桶排序是空间换时间的经典算法
// int[][] bucket = new int[10][arr.length];
// //为了记录每个桶中实际存放了多少数据,定义一个一维数组
// int[] eleCounts = new int[10];
// for (int j = 0; j < arr.length; j++) {
// int digitEle = arr[j] % 10;//个位
// //放入对应的桶
// bucket[digitEle][eleCounts[digitEle]]=arr[j];
// //对应桶数据个数+1
// eleCounts[digitEle]++;
//
// }
// //按照桶的顺序把数据取回来
// int index = 0;
// //外层遍历桶、内层遍历桶里的数据
// for (int i = 0; i < eleCounts.length; i++) {//就是10
// if (eleCounts[i]!=0){
// for (int j = 0; j < eleCounts[i]; j++) {
// arr[index]=bucket[i][j];
// index++;
// }
// }
// }
}
}