1.冒泡排序
图示 :
//冒泡排序
public class BubbleSort extends Sort {
public BubbleSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
for (int i = 0; i <arr.length ; i++) {
for (int j = 1; j <arr.length-1 ; j++) {
if (arr[j]>arr[j+1]){
swap(j,j+1);
}
}
}
System.out.println(Arrays.toString(arr));
}
}
2.选择排序
图示:
//选择排序
public class SelectSort extends Sort {
public SelectSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
for (int i = 0; i <arr.length-1; i++) {
int minindex=i;
for (int j = i+1; j <arr.length ; j++) {
if (arr[j]<arr[minindex]){
minindex=j;
}
}
swap(i,minindex);
}
System.out.println(Arrays.toString(arr));
}
}
2.快速排序
2.1单路排序
public class QuickSort extends Sort {
public QuickSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
sortsort(0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
private void sortsort(int L, int R) {
if (L>=R){
return;
}
//对数组进行划分,并返回划分后的中点
int p=partition(L,R)-1;
sortsort(0,p - 2);
sortsort(p + 1, R);
}
private int partition(int L, int R) {
int j = R+1;
int i=L+1;
int v=L;
while (i<j){
if (arr[v]<=arr[i]){
swap(i,j-1);
j--;
}else {
i++;
}
}
swap(L, j-1);
return j;
}
}
2.2双路排序
public class TwoQuickSort extends Sort {
public TwoQuickSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
onemethod(0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
private void onemethod(int L, int R) {
if (L >= R) {
return;
}
//中间值
int p = middlevalue(L, R);
onemethod(L, p - 1);
onemethod(p + 1, R);
}
private int middlevalue(int L, int R) {
//避免升序情况,让第一个元素随机和其他位置元素交换
swap(L, (int) (Math.random() * (R - L + 1) + L));
int v = arr[L];
int i = L + 1;
int j = R;
while (true) {
while (i <= R && arr[i] < v) {
i++;
}
while (j >= L + 1 && arr[j] > v) {
j--;
}
if (i > j) {
break;
}
swap(i, j);
i++;
j--;
}
swap(L, j);
return j;
}
2.3三路排序
public class ThreeQuickSort extends Sort {
public ThreeQuickSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
threequicksort(0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
private void threequicksort(int L, int R) {
if (L>=R){
return;
}
swap(L, (int) (Math.random() * (R - L + 1) + L));
int v=arr[L];
int i=L+1;
int lt=L;
int gt=R+1;
while (i<gt){
if (v<arr[i]){
swap(i,gt-1);
gt--;
}else if (v>arr[i]){
swap(i,lt+1);
i++;
lt++;
}else {
i++;
}
}
swap(L,lt);
threequicksort(L,lt-1);
threequicksort(gt,R);
}
}
3.插入排序
public class insertSort extends Sort {
public insertSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
int i = 0;
while (i <= arr.length-1) {
int j = i;
if (i == 0) {
i++;
}
while (j > 0) {
if (arr[j] < arr[j - 1]) {
swap(j, j - 1);
j--;
} else {
j--;
}
}
i++;
}
System.out.println(Arrays.toString(arr));
}
4.希尔排序
如图,如果j-gap所对应值大于j所对应值,则交换值,然后在j指向j-gap,在进行对比,直到j-gap小于0或者j-gap的对应值小于j的对应值,此时i++;这个顺序直到i遍历到数组完,在重新得到gap,是gap/2得到新的,再继续刚所述操作。
//自己写的
public class ShellSort extends Sort {
public ShellSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
int gap = arr.length / 2;
int i = gap;
int j = 0;
while (true) {
while (i <= arr.length - 1) {
j=i;
if (arr[j - gap] < arr[j]) {
i++;
} else if (arr[j - gap] > arr[j]) {
swap(j - gap, j);
j=j-gap;
while (j-gap>0){
if (arr[j-gap]<arr[j]){
i++;
break;
}
else if (arr[j-gap]>arr[j]){
swap(j-gap,j);
j=j-gap;
}else {
i++;break;
}
}
} else {
swap(j-gap+1,j);
i++;
}
}
gap = gap / 2;
i = gap;
if (gap<1){break;}
}
System.out.println(Arrays.toString(arr));
}
}
//正宗写法
public class ShellSort extends Sort{
public ShellSort(int[] arr){
super(arr);
}
@Override
public void sort() {
int len=arr.length;
for (int gap =len/2; gap >0 ; gap=gap/2) {
for (int i = gap; i <len ; i++) {
int e=arr[i];
int j=i;
while (j-gap>=0&&arr[j-gap]>e){
arr[j]=arr[j-gap];
j=j-gap;
}
arr[j]=e;
}
}
}
}
5.合并排序
public class MergeSort extends Sort {
public MergeSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
mergesort(0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
private void mergesort(int l, int r) {
if (l>=r){
return;
}
int mid=(l+r)/2;
//递归排序当前层级的右边
mergesort(l,mid);
//递归排序当前层级的左边
mergesort(mid+1,r);
//左边右边排完,进行合并,
// 如果左边的最大值小于左边的最小值则不需要合并
if (arr[mid]>arr[mid+1]){
merge(l,mid,r);
}
}
// 合并操作
private void merge(int l, int mid, int r) {
//创建了个新数组,方便比较
int[] aux=new int[r-l+1];
//复制数组
for (int k = l; k <=r ; k++) {
aux[k-l]=arr[k];
}
int i=l,j=mid+1;
for (int k=l;k<=r;k++){
//左边完毕
if (i>mid){
arr[k]=aux[j-l];
}else if (j>r){//右边完毕
arr[k]=aux[i-l];
i++;
}else if (aux[i-l]<aux[j-l]){
arr[k]=aux[i-l];
i++;
}else{
arr[k]=aux[j-l];
j++;
}
}
}
}
6.桶排序
桶排序顾名思义,就是放几个桶并且桶有范围,然后把数放进去,在桶内进行其他排序。
//桶排序
public class bucketSort extends Sort {
public bucketSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
//1.桶的个数 创建桶
int max=0,min=0;
for (int i = 0; i < arr.length ; i++) {
if (arr[i]>max){
max=arr[i];
}
if (arr[i]<min){
min=arr[i];
}
}
int bucketnum=(max-min)/ arr.length+1;
System.out.println(bucketnum+"个桶");
ArrayList<Integer>[] lists=new ArrayList[bucketnum];
for (int i = 0; i <bucketnum ; i++) {
lists[i]=new ArrayList<>();
}
//2.分配元素
for (int i = 0; i <arr.length ; i++) {
lists[(arr[i]-min)/arr.length].add(arr[i]);
}
//3.桶内排序
for (int i = 0; i < lists.length ; i++) {
lists[i].sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
}
int index=0;
for (int i = 0; i < bucketnum ; i++) {
for (int j = 0; j < lists[i].size(); j++) {
arr[index++]=lists[i].get(j);
}
}
System.out.println(Arrays.toString(arr));
}
}
7.基数排序
创建0~9个位桶,每个桶实质相当于一个队列,比如说 , 排序如图
我们先取个位排序那么应该是下图排列,然后每个桶一次出队
变成如下顺序
然后在按十位排序,继续上述操作。那么到底进行多少轮呢,取决于,原数组最大值的位数。
//基数排序
public class radixSort extends Sort {
public radixSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
//1.轮数 获取最大执行几次
int radixnum=radixmax(arr);
System.out.println("轮数为:"+radixnum);
//2.创建桶 list所有桶的集合 每一个桶是linkedList(当10个队列用)
LinkedList<Integer>[] list=new LinkedList[10];
//每一个桶中有list
for (int i = 0; i <10 ; i++) {
list[i]=new LinkedList<>();
}
//3.开始 分类-收集
for (int r = 1; r <=radixnum; r++) { //轮数
//分类过程
for (int i = 0; i < arr.length ; i++) {
list[getIndex(arr[i],r)].offer(arr[i]);
}
//收集 遍历桶
int index=0;
//收集过程
for (int i = 0; i < list.length; i++) {
while (!list[i].isEmpty()){
arr[index++]= list[i].poll();
}
}
}
System.out.println(Arrays.toString(arr));
}
private int getIndex(int num, int r) {
//345
int count=0;
for (int i = 1; i <=r ; i++) {
count=num%10;
num/=10;
}
return count;
}
private int radixmax(int[] arr) {
int max=0;
for (int i = 0; i < arr.length ; i++) {
if (arr[i]>max){
max=arr[i];
}
}
return (max+"").length();
}
}
8.计数排序
指原数组每个元素出现的次数,然后根据统计的次数排序。
1.先确定原数组最大值和最小值,根据上图最大值为6,最小值为1
2.创建一个计数数组其长度为max-min+1
3.遍历原数组,计算arr[i](当前元素)-min ,这个计算的是当前元素在计数数组的位置,然后出现一次+1.
4.然后根据次数依次放入到原数组中,num(原数组的数)=index(计数数组的下标)+min,变成
//计数排序
public class countSort extends Sort {
public countSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
//1.创建一个计数数组
int max=0,min=1;
for (int i = 0; i <arr.length ; i++) {
if (arr[i]>max){
max=arr[i];
}
if (arr[i]<min){
min=arr[i];
}
}
System.out.println("最大值:"+max);
System.out.println("最小值:"+min);
int[] countarr=new int[max-min+1];
System.out.println("计数数组长度:"+countarr.length);
//2.开始计数
for (int i = 0; i < arr.length ; i++) {
countarr[arr[i]-min]++;
}
//3.按照计数,开始排序 num=index+min
int k=0;
for (int index = 0; index <countarr.length ; index++) {
for (int count = 0; count <countarr[index] ; count++) {
int num=index+min;
arr[k++]=num;
}
}
System.out.println(Arrays.toString(arr));
}
}
附:排序接口
public abstract class Sort {
public int[] arr;
public Sort(){}
public Sort(int[] arr){
this.arr=new int[arr.length];
for (int i = 0; i <arr.length ; i++) {
this.arr[i]=arr[i];
}
}
public abstract void sort();
public void swap(int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}