面试常见的几种排序算法

一、快速排序

介绍:

快速排序的思想是分而治之,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

public class QuickSort {
    public static void main(String[] args) {
        int[] a = {8,2,1,10,9,20,5,40,22,31,7,15};
        quickSort(a,0,a.length-1);
    }
    public static void quickSort(int[] a,int left,int right){
        if(right<=left){
            return;
        }
        int centerValue =a[left];
        int min = left;
        int max = right;
        int position = left;
        while(min<max){
            do{
                if(centerValue>a[max]){
                    a[min]=a[max];
                    a[max]=centerValue;
                    position=max;
                    break;
                }
                max--;
            }while(min<max);
            do{
                if(centerValue<a[min]){
                    a[max]=a[min];
                    a[min]=centerValue;
                    position=min;
                    break;
                }
                min++;
            }while(min<max);

        }
        quickSort(a,left,position-1);
        quickSort(a,position+1,right);

    }
}

二、堆排序

介绍:

是指利用这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

public class HeapSort {
    public static void main(String[] args){
        int[] arr = {8,2,1,10,9,20,5,40,22,31,7,15};
        heapSort(arr);
        for(int temp:arr){
            System.out.print(temp+",");
        }
    }

    /**
     * 堆排序
     * @param arr
     */
    public static void heapSort(int[] arr){
        if(arr==null||arr.length<=1){
            return;
        }
        initMaxHeap(arr);
        for(int i=arr.length-1;i>=0;i--){
            exchange(arr,0,i);
            keepMaxHeap(arr,0,i);
        }
    }

    /**
     * 初始化成一个最大堆
     * @param arr
     */
    public static void initMaxHeap(int[] arr){
        for(int i = (arr.length)/2-1;i>=0;i--){
            keepMaxHeap(arr,i,arr.length);
        }
    }

    /**
     * 调整最大堆
     * @param arr
     * @param index
     * @param endIndex
     */
    public static void keepMaxHeap(int[] arr,int index,int endIndex){
        if(arr==null || index>(endIndex)/2-1){
            return;
        }
        int parentIndex = index;
        int leftIndex = index*2+1;
        int maxIndex = parentIndex;
        if(leftIndex<endIndex && arr[maxIndex]<arr[leftIndex]){
            maxIndex=leftIndex;
        }
        int rightIndex =leftIndex+1;
        if(rightIndex<endIndex && arr[maxIndex]<arr[rightIndex]){
            maxIndex=rightIndex;
        }
        if(maxIndex!=parentIndex){
            exchange(arr,maxIndex,parentIndex);
            keepMaxHeap(arr,maxIndex,endIndex);
        }
    }

    /**
     * 交换数组位置
     * @param arr
     * @param a
     * @param b
     */
    public static void exchange(int[] arr,int a, int b){
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

三、合并排序

介绍:

合并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

合并排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。合并排序也叫归并排序

public class MergeSort {
    /**
     * 递归合并两个已按升序排列的数组.
     */
    public static int[] merge(int[] a, int[] b) {
        int[] result = new int[a.length+b.length];
        mergeSort(a,b,0,0,result);
        return result;
    }
    public static void mergeSort(int[] a, int[] b,int aIndex,int bIndex,int[] result) {
        if((aIndex+bIndex)==result.length){
            return;
        }
        if(aIndex>=a.length&&bIndex<b.length){
            result[aIndex+bIndex]=b[bIndex];
            bIndex++;
        }else if(bIndex>=b.length&&aIndex<a.length){
            result[aIndex+aIndex]=b[aIndex];
            aIndex++;
        }else{
            if(a[aIndex]>=b[bIndex]){
                result[aIndex+bIndex]=b[bIndex];
                bIndex++;
            }else{
                result[aIndex+bIndex]=a[aIndex];
                aIndex++;
            }
        }
        mergeSort(a,b,aIndex,bIndex,result);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值