1.归并排序:采用分治法策略,即分而治之,先分解,在处理,后合并;
算法源码:
package com.order;
import java.util.Arrays;
public class Merger_Order {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[] A={3 ,2 ,1 ,2, 4 ,3 ,7, 6 ,9 ,0, 6};
// int[] A={1,4,9,10,2,3,7};
// merger(A,1,3,6);
mergerSort(A,0,10);
System.out.println(Arrays.toString(A));
}
public static void mergerSort(int[] A,int p,int r){
if(p<r){
int q=(p+r)/2;
mergerSort(A,p,q);
mergerSort(A,q+1,r);
merger(A,p,q,r);
}
}
//合并两个数组
public static void merger(int[] A,int p,int q,int r){
int[] L=new int[q-p+2];
int[] R=new int[r-q+1];
L[q-p+1]=10000;
R[r-q]=10000;
for(int a=p;a<=q;a++){
L[a-p]=A[a];
}
for(int a=q+1;a<=r;a++){
R[a-q-1]=A[a];
}
int i=0,j=0;
for(int k=p;k<=r;k++){
if(L[i]<=R[j]){
A[k]=L[i];
i++;
}else{
A[k]=R[j];
j++;
}
}
}
}
分析:时间复杂度为O(nlogn),空间复杂度O(n),比较好的一种排序算法,面试常问。
2.快速排序:同样采用分治思想,原址排序
Java 源码:
package com.order;
import java.util.Arrays;
public class Quick_Sort {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[] A = { 2, 8, 7, 1, 3, 5, 6, 4 };
System.out.println(Arrays.toString(quickSort(A, 0, 7)));
}
public static int[] quickSort(int[] A, int p, int r) {
if (p < r) {
int q = partition(A, p, r);
quickSort(A, p, q - 1);
quickSort(A, q + 1, r);
}
return A;
}
public static int partition(int[] A, int p, int r) {
// 取数组中最后一个元素为划分元
int x = A[r];
int i = p - 1;
for (int j = p; j < r; j++) {
if (A[j] < x) {
i++;
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
int temp = A[i + 1];
A[i + 1] = A[r];
A[r] = temp;
return i + 1;
}
}
算法分析:最坏时间复杂度O(n^2),平均时间复杂度O(nlogn),空间复杂度O(1),比较优秀的算法了,面试常问。
3.堆排序:切记堆是由数组存储,先整堆(大根堆和小根堆之分),建堆,再出元素排序。
Java 源码:
package com.order;
import java.util.Arrays;
public class Heap_Sort {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[] A={14,16,10,8,7,9,3,2,4,1};
heapSort(A,10);
System.out.println(Arrays.toString(A));
}
//堆排序的过程
public static void heapSort(int A[],int heapSize){
buildMaxHeapfy(A,heapSize);//先整大根堆
for(int i=heapSize-1;i>0;i--){
int temp=A[heapSize-1];
A[i]=A[0];
A[0]=temp;
heapSize--;
maxHeapfy(A,0,heapSize);
}
}
//整大根堆过程
public static void buildMaxHeapfy(int A[],int heapSize){
for(int i=heapSize/2;i>=0;i--){
maxHeapfy(A,i,heapSize);
}
}
//整堆过程
public static void maxHeapfy(int A[], int i,int heapSize){
//获取左孩子索引
int leftIndex=2*i+1;
//获取右孩子的节点索引
int rightIndex=2*i+2;
int max=i;
if(leftIndex<heapSize&&A[leftIndex]>A[i]){
max=leftIndex;
}
if(rightIndex<heapSize&&A[rightIndex]>A[max]){
max=rightIndex;
}
if(max==leftIndex){
int temp=A[i];
A[i]=A[leftIndex];
A[leftIndex]=temp;
maxHeapfy(A,leftIndex,heapSize);
}
if(max==rightIndex){
int temp=A[i];
A[i]=A[rightIndex];
A[rightIndex]=temp;
maxHeapfy(A,rightIndex,heapSize);
}
}
}
算法分析:时间复杂度O(nlogn),空间复杂度O(1),比较优秀算法,面试常问。
4 计数排序:切记是对某个区间内的整数进行排序
Java源码:
package com.order;
import java.util.Arrays;
public class Count_Sort {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[] A={2,5,3,0,2,3,0,3};
int [] B=new int[A.length];
countSort(A,B,5);
System.out.println(Arrays.toString(B));
}
public static void countSort(int[] A, int[] B,int k ){
//初始化计数数组每一个值都是0
int[] C=new int[k+1];
for(int i=0;i<C.length;i++){
C[i]=0;
}
//对数组A中的每一个值作为C数组下表索引,计数
for(int i=0;i<A.length;i++){
C[A[i]]=C[A[i]]+1;
}
//将C数组按照递增序列依次累加
for(int i=1;i<C.length;i++){
C[i]=C[i]+C[i-1];
}
//排序
for(int i=A.length -1;i>=0;i--){
B[C[A[i]]-1]=A[i];
C[A[i]]=C[A[i]]-1;
}
}
}
算法分析:时间复杂度O(n),空间复杂度O(n),面试很少问,时间复杂度虽然低但只能对整数有效哟。
总结:
1.其他排序算法就不提了,如冒泡,希尔,插入,基数,桶排(桶排序比较巧妙)
2.本文就以上四种算法做了源码和时空分析,算是排序算法里的佼佼者了,面试常问,意思就是说,如果面试官再问你学过什么排序算法,你就不要再提大学里的冒泡,希尔等排序算法了,很掉价的。直接说学过快排、堆排和归并排序就可;意思更说面试之前,快排和堆排算法肯定要回顾回顾的。