整数数组中的元素包含: 负数 0 正数 可能会有重复 随机数范围为-49到+49 共100个
排序算法: 选择 冒泡 插入 快速 希尔 归并 桶
代码均为升序 倒序的部分在具体的位置会有标记
package a2_sort;
import java.util.Random;
public class a01_selection {
// 选择排序核心思想 不断的选择出最小值 换位到序列最左侧
public static int[] selectionSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int min = arr[i];
int index = i;
for (int j = i+1; j < arr.length; j++) {
// 换成< 就是降序
if (min > arr[j]){
min = arr[j];
index = j;
}
}
int temp = arr[i];
arr[i] = min;
arr[index] = temp;
}
return arr;
}
public static void main(String[] args) {
int[] arr = hundred();
int[] res = selectionSort(arr);
for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
}
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
1 selectSort
package a2_sort;
import java.util.Random;
public class a02_bubble {
// 冒泡排序核心思想 像冒泡一样 不断的选择出最大值 换位序列最右侧
public static int[] bubbleSort(int[] arr) {
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]){
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
public static void main(String[] args) {
int[] arr = hundred();
int[] res = bubbleSort(arr);
for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
}
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
2 bubbleSort
package a2_sort;
import java.util.Random;
public class a03_insert {
// 插入排序核心思想: 不断和左侧元素比较 将较小的元素 插入到左侧
public static int[] insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
for (int j = i; j > 0 ; j--) {
// 换成> 就是降序 和选择排序冒泡排序不同 正好相反
if (arr[j]<arr[j-1]){
int temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
public static void main(String[] args) {
int[] arr = hundred();
int[] res = insertionSort(arr);
for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
}
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
3 insertionSort
package a2_sort;
import java.util.Random;
public class a04_quick {
// 快速排序核心思想: 2个哨兵对向出发 将相遇的位置归位 分成左右两序列后 类推
public static void quickSort(int[] arr, int left, int right) {
if (left>right)return;
int i,j,temp,t;
i=left;
j=right;
temp=arr[left];
while (i!=j){
// 分别换成<=和>= 就是降序 哨兵j让小于基准的值 存放在右侧
while (arr[j]>=temp && i<j)
j--;
while (arr[i]<=temp && i<j)
i++;
if (i<j){
t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
arr[left] = arr[i];
arr[i] = temp;
quickSort(arr, left, i-1);
quickSort(arr, i+1, right);
}
public static void main(String[] args) {
int[] arr = hundred();
quickSort(arr,0,arr.length-1);
for (int temp: arr) { if(temp != arr[arr.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
}
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
4 quickSort
package a2_sort;
import java.util.Random;
public class a05_shell {
public static int[] shellSort(int[] arr){
// 希尔排序核心思想: 将步长减半 然后进行插入排序
for (int i = arr.length/2; i > 0 ; i/=2) {
for (int j = i; j < arr.length ; j++) {
for (int k = j; k > 0 && k+1 > 0 ; k--) {
// 换成> 就是降序
if (arr[k]<arr[k-1]){
int temp = arr[k-1];
arr[k-1] = arr[k];
arr[k] = temp;
}
}
}
}
return arr;
}
public static void main(String[] args) {
int[] arr = hundred();
int[] res = shellSort(arr);
for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
}
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
5 shellSort
package a2_sort;
import java.util.Random;
public class a06_merge {
// 归并排序核心思想: 将数组不断分割 最终进行比较 排序 然后归并成一个有序数组
public static void mergeArr(int[] arr, int left, int mid, int right){
int[] b = new int[arr.length];
int p1=left, p2=mid+1, k=left;
while (p1<=mid && p2<=right) {
// 换成>= 就是降序
if(arr[p1]<=arr[p2])
b[k++] = arr[p1++];
else
b[k++] = arr[p2++];
}
while (p1<=mid) b[k++] = arr[p1++];
while (p2<=right) b[k++] = arr[p2++];
for (int i = left; i <= right; i++)
arr[i] = b[i];
}
public static void mergeSort(int[] arr, int left, int right){
if (left>=right)return;
int mid=(left+right)/2;
mergeSort(arr, left, mid);
mergeSort(arr, mid+1, right);
mergeArr(arr, left, mid, right);
}
public static void main(String[] args) {
int[] arr = hundred();
mergeSort(arr, 0, arr.length-1);
for (int temp: arr) { if(temp != arr[arr.length-1]) System.out.print(temp + ","); else System.out.println(temp); }
}
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
6 mergeSort
package a2_sort;
import java.util.Random;
public class a07_bucket {
// 桶排序核心思想: 数组的索引值是有序的 利用这个特点 在新数组中进行统计个数
public static int[] bucketSort(int[] arr){
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
}
int[] bucket = new int[max+1];
for (int i = 0; i < arr.length; i++) {
bucket[arr[i]]++;
}
int res = 0;
// 降序为 int j = arr.length-1; j > 0; j--
for (int j = 0; j < bucket.length; j++) {
while (bucket[j]-- > 0)
arr[res++] = j;
}
return arr;
}
public static void main(String[] args) {
int[] arr = {1,3,2,5,4,9,6,7,8,0};
int[] res = bucketSort(arr);
for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ","); else System.out.print(temp); }
}
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
7 bucketSort
package a2_sort;
import java.util.Arrays;
import java.util.Random;
// 解决一个问题 桶排序无法对负数进行排序
public class a08_bucket {
public static void main(String[] args) {
int[] arr = hundred();
int[] f = getArr1(arr); // 取出负数
f = bucket1(f); // 负数转正 升序
f = reverseArr(f); // 反转成倒序
f = recover(f); // 正数恢复成负数
int[] n = getArr2(arr); // 取出正数
n = bucket2(n); // 普通桶排序 将数组排序
int[] m = mergeArray(f,n); // 负数的数组 和 正数的数组 合并
printArr(m);
// 数组中的元素有100个 目测排序的准确性,数量 较耗时
// 所以使用数组的工具来验证 比较随机生成的数组 和 自己手写的方法产生的数组 应该一致
Arrays.sort(arr);
int[] arrSort = arr;
System.out.println("两个数组是否相同: : " + Arrays.equals(arr, m));
// equalsArr(arr,m);
}
// 遍历数组m 要像Arrays.toString一样 两端有[] 元素之间有逗号和1个空格 最后没有
public static void printArr(int[] m){
String res = "[";
int len = m.length-1;
for (int i = 0; i < len; i++) {
res += m[i] + ", ";
}
res += m[len] + "]";
System.out.println(res);
System.out.println(Arrays.toString(m));
// 采用str拼接的方式
/*String res1 = "[";
String res2 = "";
for (int i = 0; i < m.length-1; i++) {
res2 +=m[i];
res2 +=", ";
}
String res3 = "" + m[m.length-1];
String res4 = "]";
System.out.println(res1+res2+res3+res4);*/
}
// 比较arr和m这两个数组有什么区别
public static void equalsArr(int[] arr, int[] m){
System.out.print("数组arr的长度: " + arr.length + "m的长度: " + m.length);
System.out.println(arr.length==m.length);
System.out.print("比较2个数组中的元素是否相同: ");
int p1=0, p2=0;
boolean flag ;
for (int i = 0; i < arr.length; i++) {
if (arr[i]==m[i]) {
m[i] = -1;
} else if(i==m.length) {
System.out.println("2个数组不相同");
flag = false;
return;
}
}
}
// 合并 负数的数组 和 正数的数组
public static int[] mergeArray(int[] f, int[] n){
int p1=f.length, p2=n.length;
int[] res = new int[p1+p2];
// 先将f这个负数数组填充到res中 然后在剩余位置将n这个正数数组填充 总长100
for (int i = 0; i < p1; i++)
res[i] = f[i];
int idx = p1;
for (int j = 0; j < p2; j++)
res[idx++] = n[j];
return res;
}
// 让负数数组 变成 正数数组 方便后续的桶排序
public static int[] recover(int[] f){
for (int i = 0; i < f.length; i++)
f[i] = f[i] * (-1);
return f;
}
// 将升序的数组 变成 倒序 因为最终的效果为-49到+49 负数的部分就应该是倒序
public static int[] reverseArr(int[] f){
int temp = 0;
for (int i = 0; i < f.length/2; i++) {
temp = f[i];
f[i] = f[f.length-1-i];
f[f.length-1-i] = temp;
}
return f;
}
// 将正数的数组进行排序 必须使用桶排序
public static int[] bucket2(int[] n){
int max = Integer.MIN_VALUE;
for (int i = 0; i < n.length; i++)
max = Math.max(max, n[i]);
int[] b = new int[max+1];
for (int i = 0; i < n.length; i++)
b[n[i]]++;
int idx = 0;
for (int j = 0; j < b.length; j++) {
while (b[j]-- >0)
n[idx++] = j;
}
return n;
}
// 将负数数组升序 因为必须使用桶排序 涉及到的索引都要是正数 所以负数要暂时转换成正数
public static int[] bucket1(int[] f){
for (int i = 0; i < f.length ; i++)
f[i] = f[i] * (-1);
int max = Integer.MIN_VALUE;
for (int i = 0; i < f.length; i++)
max = Math.max(max, f[i]);
int[] b = new int[max+1];
for (int i = 0; i < f.length; i++) b[f[i]]++;
int fIdx = 0;
for (int j = 0; j < b.length; j++) {
while (b[j]-- > 0)
f[fIdx++] = j;
}
return f;
}
// 取出数组arr中存放的正数 和 0 特意将0放在这里存放属于正数的数组
public static int[] getArr2(int[] arr){
int ne = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i]>=0) ne++;
}
int nIdx = 0;
int[] n = new int[ne];
for (int i = 0; i < arr.length; i++) {
if (arr[i]>=0)
n[nIdx++] = arr[i];
}
return n;
}
// 取出数组arr中的负数 形成一个新的数组 命名为: 负数的数组
public static int[] getArr1(int[] arr){
int positiveNumber = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i]<0) positiveNumber++;
}
int fIdx = 0;
int[] f = new int[positiveNumber];
for (int i = 0; i < arr.length; i++) {
if(arr[i]<0){
f[fIdx++]=arr[i];
}
}
return f;
}
// 随机生成100个整数 含负数 0 正数 有重复 范围-49到49
public static int[] hundred(){
int[] arr = new int[100];
int res = 0;
for (int i = 0; i < arr.length; i++) {
res = new Random().nextInt(50);
if (i>50) {res = res*(-1);}
arr[i] = res;
}
return arr;
}
}
8 让桶排序可以排序负数