排序算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WANG_Chaunwang/article/details/79945142

排序算法 - Java实现

快速排序

最经典实现,worst case为O(n2)。但随机化后最坏情况也能达到O(nlog(n))
在这里提一下二叉搜索树(BST),它与快速排序有着民曲同工之妙。
比如:对6,10,13,5,8,3,2进行排序
快排,以6为key,小于6的放到左边,其他放到右边

6 10 13 5 8 3 2
i,j
6 10 13 5 8 3 2
i j
6 5 13 10 8 3 2
i j
6 5 3 10 8 13 2
i j
6 5 3 2 8 13 10
2 5 3 6 8 13 10

BST版本:比6小的都放到了左子树,其他的都放到了右子树。

            6
          /   \
         5     8
        /       \
       3         13
      /          /
     2          10

快排的代码实现

package Algorithm;

import java.util.Arrays;

public class QuickSort {

    public static void main(String[] args) {
        QuickSort qs = new QuickSort();
        int[] array = new int[]{3, 8, 4, 2, 6, 11, 13, 6};
        System.out.printf("before: %s\n", Arrays.toString(array));
        qs.quicksort(array);
        System.out.printf("after: %s\n", Arrays.toString(array));
    }

    public void quicksort(int[] array) {
        quicksort(array, 0, array.length);
    }

    private void quicksort(int[] array, int from, int to) {
        if (from >= to - 1) {
            return;
        }

        int key = array[from];
        int i, j;
        for (i = from, j = from + 1; j < to; j++) {
            if (array[j] < key) {
                swap(array, ++i, j);
            }
        }
        swap(array, from, i);
        quicksort(array, from, i);
        quicksort(array, i + 1, to);
    }

    private void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

} /*
输出结果
before: [3, 8, 4, 2, 6, 11, 13, 6]
after: [2, 3, 4, 6, 6, 8, 11, 13]
*/

堆排序(heapsort)

调整根结点为最大值(最大堆),然后把根结点的值与数组最后的值交换,并在逻辑上将数组的长度减一,重构最大堆,如此循环往复,直到遍历完最后一个元素。

代码实现

package Algorithm;

import java.util.Arrays;

public class HeapSort {

    public static void main(String[] args) {
        HeapSort heapSort = new HeapSort();
        int[] test = new int[]{7, 8, 5, 9, 3, 2, 6};
        System.out.printf("before: %s\n",Arrays.toString(test));
        System.out.printf("after: %s\n",Arrays.toString(heapSort.heapsort(test)));    }

    public void adjust(int[] left, int i, int len) {

        int lChild = 2 * i + 1;
        int rChild = 2 * i + 2;
        int max = i;

        if (i < len) {
           if (lChild < len && left[lChild] > left[max])
               max = lChild;
           if (rChild < len && left[rChild] > left[max])
               max = rChild;
           if (i != max) {
               swap(left, i, max);
               adjust(left, max, len);
           }
        }
    }

    public int[] heapsort(int[] unsorted) {

        for (int i = (unsorted.length) / 2 - 1; i >= 0; i--) {
            adjust(unsorted, i, unsorted.length - 1);
        }

        for (int i = unsorted.length - 1; i > 0; i--) {
            swap(unsorted, 0, i);
            adjust(unsorted, 0, i);
        }

        return unsorted;
    }
    public void swap(int[] target, int i, int j) {
        int tmp = target[i];
        target[i] = target[j];
        target[j] = tmp;
    }
}/*
输出结果
before: [7, 8, 5, 9, 3, 2, 6]
after: [2, 3, 5, 6, 7, 8, 9]
*/

插入排序(insertion sort)

插入排序假设前i - 1个元素已经排好序,然后把第i个元素“插入”到适当的位置。

插排的代码实现


import java.util.Arrays;
import java.util.Comparator;

public class InsertionSort {

    public <T extends Comparable> T[] sort_asc(T[] array, Comparator<T> cmp) {
        int len = array.length;
        T key;
        for (int i = 1; i < len; i++) {
            key = array[i];
            int j = i - 1;
            while (j >= 0 && cmp.compare(array[j], key) > 0) {
                array[j + 1] = array[j];
                j--;
            }
            array[j + 1] = key;
        }
        return array;
    }

    public static void main(String[] args) {
        InsertionSort is = new InsertionSort();
        Integer[] array = new Integer[]{5, 2, 4, 6, 1, 3,};
        Comparator<Integer> cmp = Comparator.naturalOrder();

        System.out.println(Arrays.toString(is.sort_asc(array, cmp)));

    }
} /* Output:
[1, 2, 3, 4, 5, 6]
*/

归并排序

现在我们有两叠扑克牌,正面朝上,并且每一叠扑克牌都是排好序的,牌堆顶部的牌最小。现在我们要把这两叠扑克牌合成一叠,使之正面朝下放置,我们只需要把两个牌堆顶的牌比较一下,每次取较小的,如此往复,因为每次都是取最小的牌,所以最终得到的合并的牌堆也是排好序的。

    public int[] mergesort(int[] array) {
        try {
            mergesort(array, 0, array.length);
        } catch (NullPointerException e) {
            throw new RuntimeException(e);
        }

        return array;
    }

    private void mergesort(int[] array, int p, int r) {
        if (p < r - 1) {
            int q = (p + r) / 2;
            mergesort(array, p, q);
            mergesort(array, q, r);
            merge(array, p, q, r);
        }

    }

    private void merge(int[] array, int p, int q, int r) {
        int n1 = q - p;
        int n2 = r - q;
        int[] left = new int[n1 + 1], right = new int[n2 + 1];
        System.arraycopy(array, p, left, 0, n1);
        System.arraycopy(array, q, right, 0, n2);
        left[n1] = Integer.MAX_VALUE;
        right[n2] = Integer.MAX_VALUE;
        int i = 0, j = 0;
        for (int k = p; k < r; k++) {
            if (left[i] <= right[j])
                array[k] = left[i++];
            else
                array[k] = right[j++];
        }
    }

其他排序待补充

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页