【排序算法】——快速排序、归并排序的排序原理及Java实现

5.快速排序

(1)算法描述
     快速排序是一种划分交换排序,采用分治的策略(分治法)。通过一趟排序
     将待排序序列划分为两个独立的部分,其中一部分的记录的关键字均小于另
     外一部分的关键字。

     分法法的基本思想:将原问题分解为若干个规模更小但是结构和原问题相似
     的子问题,递归地解决这些子问题,然后将这些子问题的解组合成原问题的解。
(2)算法实现
     a.从数组序列中选择一个“基准元素”(此文中以每个序列第一个元素为准)
     b.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准
     值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,
     该基准就处于数列的中间位置。这个称为分区操作
     c.递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
public class Sort {
    public static void main(String[] args) {
        int [] arr = new int[]{4,2,1,6,3,6,0,-5,1,1};
        quickSort(arr,0,arr.length-1);
        //遍历打印排序后的数组
        for(int i = 0; i < arr.length;i++){
            System.out.print(arr[i]+" ");
        }
    }
/**
     *快速排序
     * @exception: array为待排序序列,low为要排序序列的下界,high为要排序序列的上界
     * @date: 2018/8/16 9:41
     */
    public static void quickSort(int[] array,int low,int high){
        if(array==null||array.length==0){
            System.out.println("array is null");
        }
        //划分后的基准元素
        int standard;
        //区间长度小于1不需要再进行排序
        if(low>=high){
            return;
        }
        //对low……high进行划分
        standard = partition(array,low,high);
        //对左区间进行递归排序
        quickSort(array,low,standard-1);
        //对右区间进行递归排序
        quickSort(array,standard+1,high);
    }
    /**
     *对区间进行划分
     * @date: 2018/8/16 9:49
     */
    private static int partition(int[] array, int low, int high) {
        //进行临界判断
        if(array==null||array.length==0){
            return 0;
        }
        //基准元素,以区间第一个元素为准
        int standardValue = array[low];
        //区间长度小于1不需要进行划分
        if(low>=high){
            return low;
        }
        //区间两端交替向中间扫描,直至low=high为止
        while(low//(standardValue相当于在位置low上)
            while((low//从右向左扫描,查找第一个关键字小于基准元素standardValue值的记录
                high--;
            }
            //表示找到小于基准元素standardValue值的记录
            if(low//相当于交换low和high位置的值
                array[low++] = array[high];
            }
            //(standardValue相当于在位置high上)
            while((low//从左向右扫描,查找第一个关键字大于standardValue值的记录
                low++;
            }
            //表示找到大于基准元素standardValue值的记录
            if(low//交换low和high的值
                array[high--] = array[low];
            }
        }
        //基准位置被最后定位
        array[low] = standardValue;
        return low;
    }
}

6. 归并排序

(1)算法描述
   归并算法是在归并操作上的一种有效的排序算法,同样采用分治法。是将已经有序
   的子序列进行合并,得到完全的有序序列,即先使得子序列有序,再使子序列段有
   序,将两个有序序列合并为一个有序序列,称为“二路合并”。
(2)算法实现
    a.将长度为n的序列划分为长度为n/2的两个子序列。
    b.分别对这两个子序列采用归并排序。
    c.将这两个已经有序的子序列进行合并。
public class Sort {
    public static void main(String[] args) {
        int [] arr = new int[]{4,2,1,6,3,6,0,-5,1,1};
      quickSort(arr,0,arr.length-1);
        mergeSort(arr);
        //遍历打印排序后的数组
        for(int i = 0; i < arr.length;i++){
            System.out.print(arr[i]+" ");
        }
    }
 /**
     *归并排序
     * array为待排序序列,left、right为序列的左右边界,temp为和原序列长度相等的临时序列
     * @date: 2018/8/16 11:31
     */
    public static void mergeSort(int[] array){
        //在排序前创建与原数组大小相等的临时数组,避免递归过程中频繁开辟空间
        int[] temp = new int[array.length];
        mergeSort(array,0,array.length-1,temp);
    }
    private static void mergeSort(int[] array,int left,int right,int[] temp){
        if(leftint mid = left + (right-left)/2;
            //左半边序列进行归并排序,使得其有序
            mergeSort(array,left,mid,temp);
            //有半边序列进行归并排序,使得其有序
            mergeSort(array,mid+1,right,temp);
            //将两个子序列进行合并
            merge(array,left,mid,right,temp);
        }
    }
    private static void merge(int[] array,int left,int middle,int right,int[] temp){
        if(array==null||array.length==0){
            System.out.println("array is null");
        }
        //左序列指针指向
        int leftPoint = left;
        //有序列指针指向
        int rightPoint = middle+1;
        //临时数组的指针指向
        int tempPoint = 0;
        while (leftPoint<=middle&&rightPoint<=right){
            if(array[leftPoint]<=array[rightPoint]){
                temp[tempPoint++] = array[leftPoint++];
            }else{
                temp[tempPoint++] = array[rightPoint++];
            }
        }
        //将左半序列中的元素添加至temp数组中
        while (leftPoint<=middle){
            temp[tempPoint++] = array[leftPoint++];
        }
        //将右半序列中的元素添加至temp数组中
        while(rightPoint<=right){
            temp[tempPoint++] = array[rightPoint++];
        }
        tempPoint = 0;
        //将temp中元素拷贝至原数组中
        while (left<=right){
            array[left++] = temp[tempPoint++];
        }
    }
}

你可能感兴趣的:(Java面试宝典,数据结构——Java)