排序算法实现与比较

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.本文就以上四种算法做了源码和时空分析,算是排序算法里的佼佼者了,面试常问,意思就是说,如果面试官再问你学过什么排序算法,你就不要再提大学里的冒泡,希尔等排序算法了,很掉价的。直接说学过快排、堆排和归并排序就可;意思更说面试之前,快排和堆排算法肯定要回顾回顾的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值