015-算法面试必备-常见排序算法(快排,归并,堆排,插入排序,选择排序,冒泡排序)

今天推送常见的排序算法。

这些算法,在实习面试过程面过很多次,比如快排,我记得至少在面试过程中写过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(' ');
		}
	}
}

猜你喜欢

转载自blog.csdn.net/u013385925/article/details/83513683