八大排序(2)

交换排序

冒泡排序

void sort(int[] array){
	boolean isCharge=false;
    for(int i=0;i<array.length;i++){
        isCharge=false;
        for(int j=1;j<array.length-i;++j){
            if(array[j-1]>array[j]){
                swap(arr,j-1,j);
                isCharge=true;
            }
         }
         if(!isCharge){
             return;
         }
    }
}
时间复杂度 空间复杂度 稳定性 适合场景
O(N^2) O(1) 稳定 元素基本有序,数量较小

快排
递归

  1. 从待排序区间选择一个数,作为基准值key;
  2. partion: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可以包含相等的)放到基准值的右边;
  3. 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1,代表已经有序,或者小区间的长度 == 0,代表没有数据。
void quickSort(int[] arr,int left,int right){
    if((right-left)<16){
        //其他排序方式优化
    } else{
        int div=partion2(arr,left,right);
        quicksort(arr,left,div-1);
        quicksort(arr,div+1,right);
    }
}
//三数取中
int getIndexOfMiddle(int[] array,int left,int right){
    int mid=left+((right-left)>>1);
    if(array[left]<array[right]){
        if(array[mid]<array[left]){
            return left;
        }else if(array[mid]>array[right]){
            return right;
        }else{
            return mid;
        }
    }else{
        if(array[mid]>array[left]){
            return left;
        }else if(array[mid]<array[right]){
            return right;
        }else{
            return mid;
        }
    }
}
// hoare
int partion(int[]arr,int left,int right){
    int key=right;
    while(left<right){
        while(left<right&&arr[left]<=arr[key]){
            left++;
        }
        while(left<right&&arr[right]>=arr[key]){
            right--;
        }
        if(left<right){
            swap(arr,left,right);
        }
    }
    swap(arr,key,left);
    return left;
}
//挖坑法
void partion1(int[] arr,int left,int right){
    int mid=getIndexOfMiddle(arr,left,right);
    swap(arr,mid,left);
    int key=arr[left];
    while(left<right){
        while(left<right&&arr[right]>key){
            right--;
        }
        arr[left]=arr[right];
        while(left<right&&arr[left]<key){
            left++;
        }
        arr[right]=arr[left];
     }
        arr[left]=key;
        return left;
}
   
int partion2(int[] arr,int left,int right){
    int cur=left;
    int prev=cur-1;
    int key=arr[right];
    while(cur<right){
        if(arr[cur]<key&&++prev!=cur){
            swap(arr,prev,cur);
        }
        ++cur;
    }
    if(++prev!=right){
        swap(arr,prev,right);
    }
    return prev;
}

非递归

void quicksort(int[] array){
    Stack<Integer> s=new Stack<>();
    s.push(array.length-1);
    s.push(0);
    while(!s.isEmpty()){
         int left=s.pop();
         int right=s.pop();
         if(right-left>0){
            int div=partion2(array,left,right);
            s.push(right);
            s.push(div+1);
            s.push(div-1);
            s.push(left);
         }
    }
}
时间复杂度 空间复杂度 稳定性 适合场景
O(NlogN) O(logN) 不稳定 元素数量较大

归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

void sort(int[] arr) {
    mergeSort(arr,0,arr.length-1);
}

void mergeSort(int[] arr, int start, int end) {
    if(end-start>0){
        int mid=start+((end-start)>>1);
        mergeSort(arr,start,mid);
        mergeSort(arr,mid+1,end);
        merge(arr,start,mid,end);
    }
}
void merge(int[] arr,int left,int mid,int right){
    int[] tmp=new int[right-left+1];
    int index=0;
    int p1=left;
    int p2=mid+1;
    while(p1<=mid&&p2<=right){
        if(arr[p1]<=arr[p2]){
            tmp[index++]=arr[p1++];
        }else{
            tmp[index++]=arr[p2++];
        }
    }
    while(p1<=mid){
        tmp[index++]=arr[p1++];
    }
    while(p2<=right){
        tmp[index++]=arr[p2++];
    }
    System.arraycopy(tmp,0,arr,left,tmp.length);
}

非递归

void mergeSort1(int[]arr){
    int gap=1;
    while(gap<arr.length){
        for(int i=0;i<arr.length;i+=gap*2){
            int left=i;
            int right=left+gap*2-1;
            int mid=left+((right-left)>>1);
            if(mid>=arr.length){
                mid=arr.length-1;
            }
            if(right>=arr.length){
                right=arr.length-1;
            }
            merge(arr,left,mid,right);
         }
            gap<<=1;
     }
}
时间复杂度 空间复杂度 稳定性 适合场景
O(NlogN) O(N) 不稳定 元素数量较大

计数排序

void countSort(int[]array){
    int min=array[0];
    int max=array[0];
    for(int i = 0; i <array.length ; i++) {
        if(array[i]>max){
            max=array[i];
        }
        if(array[i]<min){
            min=array[i];
        }
     }
     int range=max-min+1;
     int[] arrayCount=new int[range];

     for(int i = 0; i <array.length ; i++) {
         arrayCount[array[i]-min]++;
     }
     int index=0;
     for(int i = 0; i <range ; i++) {
         while(arrayCount[i]!=0){
             array[index++]=i+min;
             arrayCount[i]--;
         }
     }
}

猜你喜欢

转载自blog.csdn.net/qq_42174669/article/details/105484006