今天推送常见的排序算法。
这些算法,在实习面试过程面过很多次,比如快排,我记得至少在面试过程中写过3次。
堆排在找实习过程中写过两次。归并排序写过一次,在面美团的时候。
比较重视编程能力的一些国企,可能直接回让你写相关的排序算法
这些排序算法作为基础,在面试的过程中必须做到手写无BUG。
当然这些算法只是基础,还有根据这些算法衍生出来的众多的算题。
选择排序,是一个比较有意思的排序算法,在近乎有序的情况下,复杂度近乎为O(n)
我还是建议,如果你不理解这个算法,不妨先写下来,然后手动调试一下,理解算法的思想。
那下面我们来看看这些算法的具体实现吧。
快排的实现
这里实现了两路快速排序
这里使用了随机化的思想
public class QucikSort {
private QucikSort(){}
private static void swap(Comparable[] arr, int i, int j) {
Comparable t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
private static int partition(Comparable[] arr,int l,int r){
swap(arr,l,(int)(Math.random()*(r-l+1)) + l); //随机化的思想
Comparable v = arr[l];
int i = l+1;
int j = r;
while(true){
while(i<=r&&arr[i].compareTo(v)<0)i++;
while(j>=l+1&&arr[j].compareTo(v) > 0)j--;
if(i > j)break;
swap(arr,i,j);//在这个位置,i和j首次出现了 。arr[i]>v首次出现,arr[j]<v首次出现
i++;
j--;
}
swap(arr,l,j);
return j;
}
private static void sort(Comparable[] arr, int l, int r){
if(r<l)return ;
int p = partition(arr, l, r);
sort(arr, l, p-1 );
sort(arr, p+1, r);
}
public static void sort(Comparable[] arr){
int n = arr.length;
sort(arr,0,n-1);
}
public static void main(String[] args){
Comparable[] arr = {43,13,14,3,5,33,66,88,14,22};
QucikSort.sort(arr);
for (int i = 0;i<arr.length;i++){
System.out.print(arr[i]);
System.out.print(' ');
}
}
}
归并排序的实现
public class MergeSort {
private MergeSort(){}
private static void merge(int[]arr,int l,int mid,int r){
int[] aux = Arrays.copyOfRange(arr,l,r+1);
int i = l;
int j = mid + 1;
for(int k = l;k<=r;k++){
if(i > mid){
arr[k]=aux[j-l];
j++;
}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++;
}
}
}
private static void sort(int[]arr,int l,int r){
if(l>=r)return;
int mid = l+(r-l)/2;
sort(arr,l,mid);
sort(arr,mid+1,r);
merge(arr,l,mid,r);
}
public static void sort(int[] arr){
int n = arr.length;
sort(arr,0,n-1);
}
public static void main(String[] args){
int[] arr = {43,13,14,3,5,33,66,88,14,22};
MergeSort.sort(arr);
for (int i = 0;i<arr.length;i++){
System.out.print(arr[i]);
System.out.print(' ');
}
}
}
堆排的实现
public class HeapSort {
private static void swap(int[]arr,int l,int r){
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
private HeapSort(){}
//n个节点以k为父节点进行shiftDown操作
private static void shiftDown(int[]arr,int n,int k){
while(2*k+1 < n){
int j= 2*k+1; //左节点
if(j+1 < n&& arr[j]<arr[j+1]){
j++;
} //选择较大的一个
if(arr[k] > arr[j])break; //父节点已经大于两个子节点
swap(arr,k,j);
k=j;
}
}
public static void sort(int[] arr){
int n = arr.length;
//构造一个堆
for(int i =(n-1-1)/2;i>=0;i--){
shiftDown(arr,n,i);
}
//排序
for(int i = n-1;i>0;i--){
swap(arr,i,0);
shiftDown(arr,i,0);
}
}
public static void main(String[] args){
int[] arr = {43,13,14,3,5,33,66,88,14,22};
MergeSort.sort(arr);
for (int i = 0;i<arr.length;i++){
System.out.print(arr[i]);
System.out.print(' ');
}
}
}
插入排序
插入排序对于近乎有序的数组,其复杂度为o(n),
public class InsertSort {
private InsertSort(){}
public static void sort(int[] arr){
int n = arr.length;
for(int i = 0;i<n;i++){
int temp = arr[i];
int j =i;
for(;j>0&&arr[j-1]>temp;j--){
arr[j]=arr[j-1];
}
arr[j]= temp;
}
}
public static void main(String[] args){
int[] arr = {43,13,14,3,5,33,66,88,14,22};
InsertSort.sort(arr);
for (int i = 0;i<arr.length;i++){
System.out.print(arr[i]);
System.out.print(' ');
}
}
}
选择排序
public class SelectSort {
private SelectSort(){};
private static void swap(Comparable[] arr ,int i,int j){
Comparable t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
public static void sort(Comparable[] arr){
int n = arr.length;
for(int i = 0;i<n;i++){
int minIndex = i;
for(int j = i+1;j<n;j++){
if(arr[j].compareTo(arr[minIndex]) < 0){
minIndex = j;
}
}
swap(arr,i,minIndex);
}
}
public static void main(String[] args){
Comparable[] arr = {43,13,14,3,5,33,66};
SelectSort.sort(arr);
for (int i = 0;i<arr.length;i++){
System.out.print(arr[i]);
System.out.print(' ');
}
}
}
冒泡排序
public class BubbleSort {
private BubbleSort(){};
private static void swap(Comparable[] arr ,int i,int j){
Comparable t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
public static void sort(Comparable[] arr){
int n = arr.length;
for(int i = 0;i<n;i++){ //外层控制循环趟数,内环控制,每一趟排序多少次
for(int j = 0;j<n-i-1;j++){
if(arr[j].compareTo(arr[j+1]) > 0){
Comparable temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
}
public static void main(String[] args){
Comparable[] arr = {43,13,14,3,5,33,66};
BubbleSort.sort(arr);
for (int i = 0;i<arr.length;i++){
System.out.print(arr[i]);
System.out.print(' ');
}
}
}