版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cyn_653620/article/details/81780989
1)冒泡排序
/**
* 冒泡排序,时间复杂度 O(n^2) 最优 O(n) 最差 O(n^2) 稳定
* @param arr
*/
public static void 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];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
2)选择排序
/**
* 选择排序,时间复杂度 O(n^2) 最优 O(n^2) 最差 O(n^2) 不稳定
* @param arr
* @param start
* @param end
*/
public static void selectSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
int min = i;
for(int j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
int temp = arr[j];
arr[j] = arr[min];
arr[min] = temp;
}
}
}
}
3)插入排序
/**
* 插入排序,时间复杂度 O(n^2) 最优 O(n) 最差 O(n^2) 稳定
* @param arr
*/
public static void insertSort(int[] arr){
for(int i=1;i<arr.length;i++){
//拿出一张牌
int get = arr[i];
int j=i-1;
while(j>=0&&get<arr[j]){
arr[j+1]=arr[j];
j--;
}
//插入
arr[j+1]=get;
}
}
4)二分法插入排序
/**
* 二分法插入排序,时间复杂度 O(n^2) O(nlogn) 最差 O(n^2) 稳定
* @param arr
*/
public static void insertSortDichotomy(int[] arr){
for(int i=1;i<arr.length;i++){
//拿出一张牌
int get = arr[i];
int left=0;
int right = i-1;
//二分法查找插入位置
while(left<=right){
int mid = (left+right)/2;
if(arr[mid]>get){
right=mid-1;
}else{
left=mid+1;
}
}
for(int j=i-1;j>=left;j--){//把插入位置之后的牌依次后挪,腾出位置
arr[j+1]=arr[j];
}
//插入牌
arr[left]=get;
}
}
5)快速排序
/**
* 快速排序,时间复杂度 O(nlogn) 最差情况为O(n^2),最优 O(logn)
* @param arr
*/
public static void quickSort(int[] arr){
quickSort(arr,0,arr.length-1);
}
public static void quickSort(int[] arr,int start,int end){
//递归出口
if(start>=end){
return;
}
int index = arr[start];
int i= start;
int j = end;
while(i<j){
//从右往左,找比基准数小的数
while(i<j&&arr[j]>index){
j--;
}
if(i<j){
arr[i] = arr[j];
}
//从左往右,找比基准数大的数
while(i<j&&arr[i]<=index){
i++;
}
if(i<j){
arr[j] = arr[i];
}
arr[i] = index;
}
//分治法-对基准数左右进行快速排序
quickSort(arr,start,i-1);
quickSort(arr,i+1,end);
}
6)归并排序
//归并排序 ,时间复杂度 O(nlogn) 最差情况为 O(nlogn),最优 O(nlogn) 稳定
public static void mergeSort(int[] arr){
mergeSort(arr,0,arr.length-1);
}
public static void mergeSort(int[] arr, int start, int end){
if(start<end){
int mid = (start+end)/2;
mergeSort(arr,start,mid);//左边有序
mergeSort(arr,mid+1,end);//右边有序
Merge(arr,start,mid,end);
}
}
public static void Merge(int[] arr,int start,int mid,int end){
int[] temp = new int[arr.length];
int i = start;
int j = mid+1;
int k = start;
//从两边取,直到一边取完
while(i<=mid&&j<=end){
if(arr[i]<arr[j]){//拿出较小,放入新数组
temp[k++] = arr[i++];
}else{
temp[k++] = arr[j++];
}
}
//在剩下的一边中依次取
while (i <= mid)
temp[k++] = arr[i++];
while (j <= end)
temp[k++] = arr[j++];
for(i=start;i<=end;i++){//将排好数组覆盖给原数组
arr[i] = temp[i];
}
}
7)堆排序
以数组形式代替堆结构,实现堆排序
/**
* 堆排序,时间复杂度 O(nlogn) 最差情况为 O(nlogn),最优 O(nlogn) 不稳定
* @param arr
*/
public static void heapSort(int[] arr){
//建立初始堆
for(int i=(arr.length-1)/2;i>=0;i--){
heapOne(arr,arr.length,i);
}
//依次拿出堆顶元素
int n = arr.length;
int[] temp = new int[arr.length];
while(n>0){
temp[arr.length-n]=arr[0];
arr[0] = arr[n-1];//最后一个叶子节点移动到堆顶
n--;
heapOne(arr,n,0);
}
for(int j=0;j<arr.length;j++){//将排好数组覆盖给原数组
arr[j] = temp[j];
}
}
//做筛选,合格的二叉堆
public static void heapOne(int[] arr,int n,int k){
int k1 = 2*k+1;
int k2 = 2*k+2;
if(k1>n&&k2>n)//已经没有子节点,自己已经是叶子了
return;
int child_left = Integer.MAX_VALUE;
int child_right = Integer.MAX_VALUE;
if(k1<n){
child_left = arr[k1];
}
if(k2<n){
child_right = arr[k2];
}
if(arr[k]<child_left&&arr[k]<child_right){
return;//满足堆的要求
}
if(child_left<child_right){//找出较小的进行交换
int temp = arr[k];
arr[k] = arr[k1];
arr[k1] = temp;
heapOne(arr,n,k1);//筛选子节点
}else{
int temp = arr[k];
arr[k] = arr[k2];
arr[k2] = temp;
heapOne(arr,n,k2);//筛选子节点
}