排序算法

136 阅读3分钟

快速排序
归并排序
堆排序

快速排序

快速排序wiki
算法:
快速排序使用分治法策略来把一个序列分为较小和较大的2个子序列,然后递归地排序两个子序列。
步骤为:
1. 挑选基准值:从数列中挑出一个元素,称为“基准”(pivot),
2. 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成,
3. 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。

算法实现:

public class QuickSort {
    public static void main(String[] args) {
        int[] waitSort = { 100, 50, 30, 20, 40, 70, 80 };
        QuickSort quickSort = new QuickSort();
        quickSort.quickSort(waitSort, 0, waitSort.length - 1);
        System.out.println(Arrays.toString(waitSort));
    }

    private void quickSort(int[] nums, int start, int end) {
        if (start < end) {
            int partition = quickPartition(nums, start, end);
            quickSort(nums, start, partition - 1);
            quickSort(nums, partition + 1, end);
        }
    }

    private int quickPartition(int[] nums, int start, int end) {
        int pivot = nums[start];
        int left = start, right = end;
        while (left < right) {
            while (left < right && nums[left] <= pivot) left++;
            while (left < right && pivot <= nums[right]) right--;
            if (left < right) {
                swap(nums, left, right);
            }
        }
        return left;
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

归并排序

归并排序wiki
算法:
归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
递归法(Top-down)
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4. 重复步骤3直到某一指针到达序列尾
5. 将另一序列剩下的所有元素直接复制到合并序列尾
迭代法(Bottom-up) 原理如下(假设序列共有n个元素): 1. 将序列每相邻两个数字进行归并操作,形成ceil(n/2)个序列,排序后每个序列包含两/一个元素 2. 若此时序列数不是1个则将上述序列再次归并,形成ceil(n/4)个序列,每个序列包含四/三个元素 3. 重复步骤2,直到所有元素排序完毕,即序列数为1

算法实现:

public class MergeSort {

    public static void main(String[] args) {
        int[] waitSort = { 100, 50, 30, 20, 40, 70, 80 };
        MergeSort mergeSort = new MergeSort();
        mergeSort.mergeSort(waitSort, 0, waitSort.length - 1);
        System.out.println("MergeSort");
        System.out.println(Arrays.toString(waitSort));
    }

    private void mergeSort(int[] nums, int start, int end) {
        if (start >= end) return;
        int mid = start + (end - start) / 2;
        mergeSort(nums, start, mid);
        mergeSort(nums, mid + 1, end);
        merge(nums, start, mid, end);
    }

    private void merge(int[] nums, int start, int mid, int end) {
        int[] temp = new int[end - start + 1];
        int p1 = start, p2 = mid + 1;
        int p = 0;
        while (p1 <= mid && p2 <= end) {
            if (nums[p1] < nums[p2]) temp[p++] = nums[p1++];
            if (nums[p1] >= nums[p2]) temp[p++] = nums[p2++];
        }
        while (p1 <= mid) temp[p++] = nums[p1++];
        while (p2 <= end) temp[p++] = nums[p2++];
        for (int i = 0; i < temp.length; ++i) {
            nums[start + i] = temp[i];
        }
    }
}

堆排序

堆排序wiki
算法实现:

public class HeapSort {

    public static void main(String[] args) {
        int[] waitSort = { 100, 50, 30, 20, 40, 70, 80 };
        int size = waitSort.length;

        HeapSort heapSort = new HeapSort();
        for (int i = 0; i < size; ++i) heapSort.heapInsert(waitSort, i);

        swap(waitSort, 0, --size);
        while (0 < size) {
            heapSort.heapify(waitSort, 0, size);
            swap(waitSort, 0, --size);
        }
        System.out.println("HeapSort");
        System.out.println(Arrays.toString(waitSort));
    }

    private void heapInsert(int[] nums, int index) {
        while (nums[(index - 1) / 2] < nums[index]) {
            swap(nums, index, (index - 1) / 2);
            index = (index - 1) / 2;
        }
    }

    private void heapify(int[] nums, int index, int size) {
        int left = 2 * index + 1;
        while (left < size) {
            int largest  = (left + 1 < size && nums[left] < nums[left + 1]) ? left + 1 : left;
            largest = (nums[largest] < nums[index]) ? index : largest;
            if (largest == index) break;
            swap(nums, index, largest);
            index = largest;
            left = 2 * index + 1;
        }
    }

    public static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

}