【算法学习】快速排序算法实现(Java)

快速排序是一个很经典的排序算法,,面试很喜欢问,十分重要,最近回顾了一下快排,用Java做以实现。

一,基本思想
快排,是基于分治策略的一种排序算法。(从小到大为例)
【1】选择一个基准
【2】分别从两头进行遍历,把大于基准的放在左边,小于基准的放在右边,最终把基准插入即可。
【3】分别对左右两块进行【1】【2】操作,,直至快中只有一个元素。

有点负责,简化一下:“找基准,分两块,递归。”

二,实现算法

快速排序实现算法如下:

private static void quickSort(int[] array) {
        if (array != null) {
            quickSort(array, 0, array.length - 1);
        }
    }

    private static void quickSort(int[] array, int start, int end) {
        if (start >= end || array == null) {    //null校验
            return;
        }
        int p = partition(array, start, end);//大数放左边,,小数放右边
        quickSort(array, start, p - 1);//对左边递归排序
        quickSort(array, p + 1, end);//对右边递归排序
    }

**private static int partition(int[] array, int start, int end)**,,方法两种实现
【实现1】
 private static int partition(int[] array, int start, int end) {
        int first = array[start];//以第一个为基准
        int i = start + 1, j = end;
        while (i < j) {//i == j是不容易发生的,,除非j = end,,i = end
            while (array[i] <= first && i < end) {//等于时也算小,大于end就越界了
                i++;
            }
            while (array[j] > first && j > start) {//大于等于start,,是为了和
                j--;
            }
            if (i < j) {//利用异或交换array[i]和array[j]
                array[i] = array[i] ^ array[j];
                array[j] = array[j] ^ array[i];
                array[i] = array[i] ^ array[j];
            }
        }
        if (j != start) {//结束时,array[j]是小于first,,所以需要把小于的和first互换
            array[start] = array[start] ^ array[j];
            array[j] = array[j] ^ array[start];
            array[start] = array[start] ^ array[j];
        }
        return j;//返回基准位置
    }


【实现2】
 private static int partition(int[] array, int start, int end) {
        int last = array[end];//以最后一个为基准
        int i = start, j;
        for (j = start; j <= end - 1; j++) {
            if (array[j] <= last) {
                if (i != j) {//交换时,array[i]是大于基准的,,array[j],小于基准
                    array[i] = array[i] ^ array[j];
                    array[j] = array[j] ^ array[i];
                    array[i] = array[i] ^ array[j];
                }
                i++;
            }
        }
        if (i != end) {//如果分成两块,则需要把基准数换到第二块的首位。反之array[i],,即为end
            array[i] = array[i] ^ array[end];
            array[end] = array[end] ^ array[i];
            array[i] = array[i] ^ array[end];
        }
        return i;   //返回基准位置
    }
三,测试完整代码
package ddchuxing;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zsl on 2017/8/26.
 */
public class QuicSort {
    public static void main(String[] args) {
        int array[] = {13, 14, 13, 4, 5, 6, 7, 7, 10, -1, 15};
        quickSort(array);
        System.out.println("快排结果");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + "   ");
        }
    }

    private static void quickSort(int[] array) {
        if (array != null) {
            quickSort(array, 0, array.length - 1);
        }
    }

    private static void quickSort(int[] array, int start, int end) {
        if (start >= end || array == null) {    //null校验
            return;
        }
        int p = partition(array, start, end);//大数放左边,,小数放右边
        quickSort(array, start, p - 1);//对左边递归排序
        quickSort(array, p + 1, end);//对右边递归排序
    }

    /**
     * 方法一
     */
//    private static int partition(int[] array, int start, int end) {
//        int first = array[start];//以第一个为基准
//        int i = start + 1, j = end;
//        while (i < j) {//i == j是不容易发生的,,除非j = end,,i = end
//            while (array[i] <= first && i < end) {//等于时也算小,大于end就越界了
//                i++;
//            }
//            while (array[j] > first && j > start) {//大于等于start,,是为了和
//                j--;
//            }
//            if (i < j) {//利用异或交换array[i]和array[j]
//                array[i] = array[i] ^ array[j];
//                array[j] = array[j] ^ array[i];
//                array[i] = array[i] ^ array[j];
//            }
//        }
//        if (j != start) {//结束时,array[j]是小于first,,所以需要把小于的和first互换
//            array[start] = array[start] ^ array[j];
//            array[j] = array[j] ^ array[start];
//            array[start] = array[start] ^ array[j];
//        }
//        return j;//返回基准位置
//    }

    /**
     * 方法二
     *
     * @param array
     * @param start
     * @param end
     * @return
     */
    private static int partition(int[] array, int start, int end) {
        int last = array[end];//以最后一个为基准
        int i = start, j;
        for (j = start; j <= end - 1; j++) {
            if (array[j] <= last) {
                if (i != j) {//交换时,array[i]是大于基准的,,array[j],小于基准
                    array[i] = array[i] ^ array[j];
                    array[j] = array[j] ^ array[i];
                    array[i] = array[i] ^ array[j];
                }
                i++;
            }
        }
        if (i != end) {//如果分成两块,则需要把基准数换到第二块的首位。反之array[i],,即为end
            array[i] = array[i] ^ array[end];
            array[end] = array[end] ^ array[i];
            array[i] = array[i] ^ array[end];
        }
        return i;   //返回基准位置
    }
}


你可能感兴趣的:(算法学习)