package com.company;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int n = 8000000;
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = (int) (Math.random() * n);
}
System.out.println(Arrays.toString(array));
long l = System.currentTimeMillis();
radixSort(array);
long l2 = System.currentTimeMillis();
System.out.println((l2 - l) / 1000);
}
public static void radixSort(int[] array){
//1. 得到数组中最大的数的位数
int max = array[0];//假设第一数就是最大数
for (int i = 1; i < array.length; i++) {
if (array[i] > max){
max = array[i];
}
}
//得到最大数是几位数
int maxLength = (max + "").length();
//定义一个二维数组,表示 10 个桶, 每个桶就是一个一维数组
//说明
//1. 二维数组包含 10 个一维数组
//2. 为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为 arr.length
//3. 名明确,基数排序是使用空间换时间的经典算法
int[][] bucket = new int[10][array.length];
int[] bucketElementCounts = new int[10];
for (int i = 0 , n = 1; i < maxLength; i++, n *= 10) {
//(针对每个元素的对应位进行排序处理), 第一次是个位,第二次是十位,第三次是百位.
for (int j = 0; j < array.length; j++) {
//取出每个元素的对应位的值
int digitofElement = array[j] / n % 10;
//放入到对应的桶中
bucket[digitofElement][bucketElementCounts[digitofElement]] = array[j];
bucketElementCounts[digitofElement]++;
}
int index = 0;
for (int j = 0; j < bucketElementCounts.length; j++) {
if (bucketElementCounts[j] != 0){
for (int k = 0; k < bucketElementCounts[j]; k++) {
array[index++] = bucket[j][k];
}
bucketElementCounts[j] = 0;
}
}
}
}
public static void mergeSort(int[] array, int left, int right, int[] temp){
if (left < right){
int mid = (left + right) / 2;
mergeSort(array, left, mid, temp);
mergeSort(array, mid + 1, right, temp);
merge(array, left, mid, right, temp);
}
}
public static void merge(int[] array, int left, int mid, int right, int[] temp){
System.out.println("=============");
int i = left;
int j = mid + 1;
int t = 0;
while (i <= mid && j <= right){
if (array[i] <= array[j]){
temp[t] = array[i];
t++;
i++;
}else {
temp[t] = array[j];
t++;
j++;
}
}
while (i <= mid){
temp[t] = array[i];
t++;
i++;
}
while (j <= right){
temp[t] = array[j];
t++;
j++;
}
t = 0;
int tempLeft = left;
System.out.println("tempLeft=" + tempLeft + "\tright=" + right);
while (tempLeft <= right){
array[tempLeft] = temp[t];
tempLeft++;
t++;
}
}
public static void quickSort(int[] array,int left,int right){
int l = left;
int r = right;
int temp = 0;
int pivot = array[(l + r) / 2];
while (l < r){
//在 pivot 的左边一直找,找到大于等于 pivot 值,才退出
while (array[l] < pivot){
l++;
}
//在 pivot 的右边一直找,找到小于等于 pivot 值,才退出
while (array[r] > pivot){
r--;
}
//如果 l >= r 说明 pivot 的左右两的值,已经按照左边全部是
//小于等于 pivot 值,右边全部是大于等于 pivot 值
if (l >= r){
break;
}
temp = array[l];
array[l] = array[r];
array[r] = temp;
if (array[l] == pivot){
r--;
}
if (array[r] == pivot){
l++;
}
}
if (l == r){
l++;
r--;
}
if (left < r) {
quickSort(array, left, r);
}
if (right > l) {
quickSort(array, l, right);
}
}
public static void shellSort(int[] array){
int temp = 0;
for (int gap = array.length / 2;gap > 0;gap /= 2){
// 根据前面的逐步分析,使用循环处理
for (int i = gap; i < array.length; i++) {
// 遍历各组中所有的元素(共 gap 组,每组有个元素), 步长 gap
for (int j = i - gap; j >= 0; j -= gap) {
// 如果当前元素大于加上步长后的那个元素,说明交换
if (array[j] > array[j + gap]){
temp = array[j];
array[j] = array[j + gap];
array[j + gap] = temp;
}
}
}
}
}
public static void shellSort2(int[] array){
for (int gap = array.length / 2; gap > 0; gap /= 2) {
// 增量 gap, 并逐步的缩小增量
for (int i = gap; i < array.length; i++) {
// 从第 gap 个元素,逐个对其所在的组进行直接插入排序
int j = i;
int temp = array[i];
if (array[j] < array[j - gap]){
while (j - gap >= 0 && temp < array[j - gap]){
array[j] = array[j - gap];
j -= gap;
}
array[j] = temp;
}
}
}
}
public static void insertSort(int[] array) {
for (int i = 1; i < array.length; i++) {
int insertVal = array[i];
int insertIndex = i - 1;
while (insertIndex >= 0 && insertVal < array[insertIndex]) {
array[insertIndex + 1] = array[insertIndex];
insertIndex--;
}
if (insertIndex + 1 != i){
array[insertIndex + 1] = insertVal;
}
}
}
public static void selectSort(int[] array) {
//第 1 轮
for (int i = 0; i < array.length - 1; i++) {
int minIndex = i;
int min = array[i];
for (int j = i + 1; j < array.length; j++) {
if (min > array[j]) { //说明假定的最小值,并不是最小
min = array[j]; //重置 min
minIndex = j;
}
}
//将最小值,放在 arr[0], 即交换
if (minIndex != i) {
array[minIndex] = array[i];
array[i] = min;
}
}
}
public static void bubbleSort(int[] arr) {
int temp = 0;
boolean flag = false;// 标识变量,表示是否进行过交换
// 冒泡排序 的时间复杂度 O(n^2)
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]) {
flag = true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (!flag) { // 在一趟排序中,一次交换都没有发生过
break;
} else {
flag = false; // 重置 flag!!!, 进行下次判断
}
}
}
}