常见的排序:
选择排序 直接选择排序 堆排序
交换排序 冒泡排序 直接交换排序
插入排序 直接插入排序 shell排序 折半插入排序
归并排序
基数排序
1.选择排序
1.1直接选择排序
//选择排序-直接选择排序 每循环一次取出其中最大或者最小的一个 插入到靠前或者靠后的位置(当然第一次从0开始,第二次从1开始...)
public void directSelectSort(int arr[]){
System.out.println("开始"+Arrays.toString(arr));
for(int i=0;i<arr.length-1;i++){
int tmax=arr[i];
for(int j=i+1;j<arr.length-1;j++){
if(tmax>arr[j]){
tmax=arr[j];
arr[j]=arr[i];
arr[i]=tmax;
}
}
}
System.out.println("结束"+Arrays.toString(arr));
}
1.2堆排序
//选择排序-堆排序2
//选择排序-堆排序1 把数组或者其他对象 看成一棵树 ,
//利用大堆或者小堆,找到最大的,放到最后的位置,比较的时候注意:第一次数组长度为3,第二次数组长度为2...
//为什么变数组大小?因为我们每次得到的最大,最小值要插入都后面的位置中,就不需要在比较了。
public void heapSelectSort(int []arr){
System.out.println("开始"+Arrays.toString(arr));
for(int i=0;i<arr.length-1;i++){
this.heapSelectSort(arr,arr.length-i);
}
System.out.println("结束"+Arrays.toString(arr));
}
private void heapSelectSort(int []arr,int len){
if(len-2>=0){
for(int i=(len-2)/2;i>=0;i--){
int tmax=arr[i];
if(tmax<arr[i*2+1]){
tmax=arr[i*2+1];
arr[i*2+1]=arr[i];
arr[i]=tmax;
}
if(i*2+2<=len-1&&tmax<arr[i*2+2]){
tmax=arr[i*2+2];
arr[i*2+2]=arr[i];
arr[i]=tmax;
}
}
int m=arr[0];
arr[0]=arr[len-1];
arr[len-1]=m;
}
}
2.交换排序
2.1冒泡排序
//交换排序-冒泡排序 0-1比 1-2比... 如果0大于1 换下位置 最大的最后到了数组最后,下次比较的时候比较到len-1-i的位置就可以了
public void bubbleExchangeSort(int arr[]){
System.out.println("开始"+Arrays.toString(arr));
for(int i=0;i<arr.length-1;i++){
int tmp=0;
for(int j=0;j<arr.length-i-1;j++)
if(arr[j]>arr[j+1]){
tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
System.out.println("结束"+Arrays.toString(arr));
}
2.2 快速交换排序
//交换排序-快速交换排序1
public void quickExchangeSort(int arr[]){
System.out.println("开始"+Arrays.toString(arr));
this.quickExchangeSort(arr,0,arr.length-1);
System.out.println("结束"+Arrays.toString(arr));
}
//交换排序-快速交换排序2
private void quickExchangeSort(int arr[],int start,int end){
int mark=arr[start];
int i=start;
int j=end;
while(true){
if(i<j){
for(;i<j&&arr[i]<=mark;i++);
for(;j>i&&arr[j]>=mark;j--);
if(j!=i){
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
else{
if(arr[start]>arr[i]){
int tmp=arr[start];
arr[start]=arr[i];
arr[i]=tmp;
}
int tmp=arr[start];
arr[start]=arr[i-1];
arr[i-1]=tmp;
}
}else{
break;
}
}
if(start<(j-1)){
quickExchangeSort(arr,start,j-1);
}
if(end>j+1){
quickExchangeSort(arr,j+1,end);
}
}
3.插入排序
3.1直接插入排序
//直接插入排序(稳定的) 先从数组第一个开始, 一个数是有序的,然后第二个数与第一个数比较,如果第二个小,换,如果第二个数大,不换,比较第三个,以此类推
public void directInsertSort(int []arr){
System.out.println("开始"+Arrays.toString(arr));
for(int i=0;i<=arr.length-1;i++){
for(int j=0;j<i;j++){
if(arr[i]<arr[j]){
int tmp=arr[i];
for(int m=i;m>j;m--){
arr[m]=arr[m-1];
}
arr[j]=tmp;
}
}
}
System.out.println("结束"+Arrays.toString(arr));
}
3.2折半插入排序
//折半插入排序
public void halfInsertSort(int []arr){
System.out.println("开始"+Arrays.toString(arr));
for(int i=1;i<arr.length;i++){
int low=0;
int high=i-1;
int tmp=arr[i];
while(low<=high){
int min=(low+high)/2;
if(arr[min]>tmp){
high=min-1;
}else{
low=min+1;
}
}
for(int j=i;j>low;j--){
arr[j]=arr[j-1];
}
arr[low]=tmp;
}
System.out.println("结束"+Arrays.toString(arr));
}
3.3希尔排序
//希尔排序 分段 增量 此算法为参考
public void shellInsertSort(int []array){
System.out.println("开始"+Arrays.toString(array));
int out, in, tmp;
int len = array.length;
int h = 1;
while(h < len / 3)
h = h * 3 + 1;
while(h > 0){
for(int i=0;i<len;i++){
int m=0;
while(m*h+i<len){
for(int j=0;j<m&&j*h+i<len;j++){
if(array[m*h+i]<array[j*h+i]){
int n=array[m*h+i];
for(int k=m;k>j;k--){
array[k*h+i]=array[(k-1)*h+i];
}
array[j*h+i]=n;
}
}
m++;
}
}
System.out.println("增量为"+h+":"+Arrays.toString(array));
h = (h - 1) / 3;
}
System.out.println("结束"+Arrays.toString(array));
}
4.归并排序
//归并排序
public void combineSort(int []arr){
System.out.println("开始"+Arrays.toString(arr));
this.combineSort(arr,0,arr.length-1);
System.out.println("结束"+Arrays.toString(arr));
}
private void combineSort(int[] arr, int i, int length) {
if(i<length){
int center=(i+length)/2;
combineSort(arr,i,center);
combineSort(arr,center+1,length);
sort(arr,i,center,length);
}
}
private void sort(int[] data, int left, int center, int right) {
int[] tmpArr = new int[data.length];
// 右数组第一个元素索引
int mid = center + 1;
// third 记录临时数组的索引
int third = left;
// 缓存左数组第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最小的放入临时数组
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
5.基数排序
//基数排序 比较每个位数 各位,十位 比较的算法需要稳定,我使用的是直接插入排序
public void baseSort(int []arr){
System.out.println("开始"+Arrays.toString(arr));
int tmp=0;
if(arr.length>0)tmp=arr[0];
for(int i=0;i<arr.length;i++){
if(arr[i]>tmp){
tmp=arr[i];
}
}
int size=(""+tmp).length();
//System.out.println("size="+size);
//System.out.println(this.value(1, 76));
for(int k=0;k<size;k++){
for(int i=0;i<arr.length;i++){
int tm=this.value(k, arr[i]);
for(int m=i+1;m<arr.length;m++){
if(tm>this.value(k, arr[m])){
arr[m]=arr[m]+arr[i];
arr[i]=arr[m]-arr[i];
arr[m]=arr[m]-arr[i];
tm=this.value(k, arr[i]);
}
//System.out.println("**"+Arrays.toString(arr));
}
}
System.out.println("--"+Arrays.toString(arr));
}
System.out.println("结束"+Arrays.toString(arr));
}
//基数排序
private int value(int i,int key){
while(i>0){
key=key/10;
i--;
}
key=key%10;
return key;
}