简单排序算法总结

1. 选择排序、插入排序、冒泡排序

选择排序

The selection sort algorithm sorts an array by repeatedly finding the minimum element (considering ascending order) from unsorted part
and putting it at the beginning. The algorithm maintains two subarrays
in a given array.

1) The subarray which is already sorted.
2) Remaining subarray which
is unsorted.
选择排序(升序时):左边为已排序数组,右边未排序。每次排序时,选择当前最小的元素。

```
    /**
     * @param arr
     * @author fqyuan
     * @see 这里的swap操作在第二层循环之外,减少了交换的次数,改善了部分性能。
     */
    public static void selectSort(int[] arr) {

        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[minIndex] > arr[j])
                    minIndex = j;
            }
            swap(arr, minIndex, i);
        }
    }

插入排序

Insertion sort is an in-place comparison-based sorting algorithm. Here, a sub-list is maintained which is always sorted. For example, the lower part of an array is maintained to be sorted. An element which is to be inserted into this sorted sub-list, has to find its appropriate place and then it has to be inserted there. Hence the name, insertion sort.

插入排序:是一个基于比较的排序算法。该算法维护一个已排序子数列,将待插入元素插入到已排序子数列中的算法。关键在于找到要插入点的位置,这也是‘插入排序’为该名称的缘由。

/**
     * @param arr
     * @author fqyuan
     * @see A little twisted among the 3 simple sort method:
     *      select/insert/bubble.
     */
    public static void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int key = arr[i];
            int j = i - 1;
            // Find the position to insert at: j.
            for (; j >= 0 && arr[j] > key; j--)
                arr[j + 1] = arr[j];
            arr[j + 1] = key;
        }
    }

冒泡排序

Bubble sort: this is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in wrong order.
冒泡排序:冒泡排序也是一种基于比较的排序算法,通过比较相邻元素如果非升序则进行交换。该算法性能表现较差,因为其平均复杂度和最差情况复杂度都是O(n^2).

    /**
     * @param arr
     * @author fqyuan
     * @see 加入了sorted flag之后,如果是已经排序好的数组,可以大幅减少排序swap次数。
     */
    public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            boolean sorted = true;
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                    sorted = false;
                }
            }
            if (sorted)
                break;
        }
    }

2. 归并排序 Merge Sort

Merge sort is a sorting technique based on divide and conquer technique. With worst-case time complexity being O(nlognn), it’s one of the most respected algorithm.
Three steps in total to complete the merge sort.
1. If only one element in the list, it’s already sorted, return.
2. Divide the list recursively into two halves until it can no longer be divided.
3. merge the smaller lists into new list in sorted order.
归并排序:是一种采用‘分治策略’的排序算法,该算法用递归的方式将数组分为小的单元,直至不可分,采用然后将小的单元进行归并处理merge处理。
1. 判断数组元素是否只有一个,如果是,则该数组已经有序,退出。
2. 递归地将数组分为2个部分,直至该数组不在可分为止。
3. 将小的数组归并到一个新的数组中。

public static void mergeSort(int[] arr) {
        if (arr.length < 2)
            return;
        int mid = arr.length / 2;
        int[] left = new int[arr.length / 2];
        int[] right = new int[arr.length - mid];
        for (int i = 0; i < mid; i++)
            left[i] = arr[i];
        for (int i = mid; i < arr.length; i++)
            right[i - mid] = arr[i];

        mergeSort(left);
        mergeSort(right);
        merge(left, right, arr);
    }

    private static void merge(int[] left, int[] right, int[] arr) {
        int nL = left.length;
        int nR = right.length;
        int i = 0, j = 0, k = 0;
        while (i < nL && j < nR) {
            if (left[i] <= right[j])
                arr[k++] = left[i++];
            else
                arr[k++] = right[j++];
        }
        if (i < nL) {
            while (i < nL)
                arr[k++] = left[i++];
        } else {
            while (j < nR)
                arr[k++] = right[j++];
        }
    }

3. 快速排序 Quick Sort

Quick sort is a highly efficient sorting algorithm and is based on
partitioning of array of data into smaller arrays. A large array is
partitioned into two arrays one of which holds values smaller than the
specified value, say pivot, based on which the partition is made and
another array holds values greater than the pivot value.

Quick sort partitions an array and then calls itself recursively twice
to sort the two resulting subarrays. This algorithm is quite efficient
for large-sized data sets as its average and worst case complexity are
of Ο(n2), where n is the number of items.

快速排序:一种高效的排序算法,通过把待排序数组分为更小的数组进行排序的方式。排序数组被分为2个数组,其中之一所包含的值小于一个给定的值pivotValue, 另一个子数组所包含的值大于给定的值pivotValue。

public static void quickSort(int arr[]) {
        quickSort(arr, 0, arr.length - 1);
    }

    private static void quickSort(int[] arr, int startIndex, int endIndex) {
        if (startIndex < endIndex) {
            // int pivot = randomizePartiton(arr, startIndex, endIndex);
            int pivot = partition(arr, startIndex, endIndex);
            quickSort(arr, startIndex, pivot - 1);
            quickSort(arr, pivot + 1, endIndex);
        }
    }

    private static int randomizePartiton(int[] arr, int startIndex, int endIndex) {
        int randomIndex = (int) Math.floor((Math.random() * (endIndex - startIndex + 1) + startIndex));
        swap(arr, randomIndex, endIndex);
        return partition(arr, startIndex, endIndex);
    }

    private static int partition(int arr[], int startIndex, int endIndex) {
        // Randomize the pivot.

        int randomIndex = (int) Math.floor((Math.random() * (endIndex - startIndex + 1) + startIndex));
        swap(arr, randomIndex, endIndex);

        int pivotValue = arr[endIndex];
        int pivotIndex = startIndex;
        for (int i = startIndex; i < endIndex; i++) {
            if (arr[i] < pivotValue) {
                swap(arr, i, pivotIndex);
                pivotIndex++;
            }
        }
        swap(arr, pivotIndex, endIndex);

        return pivotIndex;
    }

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

4. 完整代码及运行结果

package com.fqyuan.sort;

import java.util.Random;

import org.junit.Test;

public class SortUtils {

    /**
     * @param arr
     * @author fqyuan
     * @see 这里的swap操作在第二层循环之外,减少了交换的次数,改善了部分性能。
     */
    public static void selectSort(int[] arr) {

        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[minIndex] > arr[j])
                    minIndex = j;
            }
            swap(arr, minIndex, i);
        }
    }

    /**
     * @param arr
     * @author fqyuan
     * @see 加入了sorted flag之后,如果是已经排序好的数组,可以大幅减少排序swap次数。
     */
    public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            boolean sorted = true;
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                    sorted = false;
                }
            }
            if (sorted)
                break;
        }
    }

    /**
     * @param arr
     * @author fqyuan
     * @see A little twisted among the 3 simple sort method:
     *      select/insert/bubble.
     */
    public static void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int key = arr[i];
            int j = i - 1;
            // Find the position to insert at: j.
            for (; j >= 0 && arr[j] > key; j--)
                arr[j + 1] = arr[j];
            arr[j + 1] = key;
        }
    }

    public static void mergeSort(int[] arr) {
        if (arr.length < 2)
            return;
        int mid = arr.length / 2;
        int[] left = new int[arr.length / 2];
        int[] right = new int[arr.length - mid];
        for (int i = 0; i < mid; i++)
            left[i] = arr[i];
        for (int i = mid; i < arr.length; i++)
            right[i - mid] = arr[i];

        mergeSort(left);
        mergeSort(right);
        merge(left, right, arr);
    }

    private static void merge(int[] left, int[] right, int[] arr) {
        int nL = left.length;
        int nR = right.length;
        int i = 0, j = 0, k = 0;
        while (i < nL && j < nR) {
            if (left[i] <= right[j])
                arr[k++] = left[i++];
            else
                arr[k++] = right[j++];
        }
        if (i < nL) {
            while (i < nL)
                arr[k++] = left[i++];
        } else {
            while (j < nR)
                arr[k++] = right[j++];
        }
    }

    public static void quickSort(int arr[]) {
        quickSort(arr, 0, arr.length - 1);
    }

    private static void quickSort(int[] arr, int startIndex, int endIndex) {
        if (startIndex < endIndex) {
            // int pivot = randomizePartiton(arr, startIndex, endIndex);
            int pivot = partition(arr, startIndex, endIndex);
            quickSort(arr, startIndex, pivot - 1);
            quickSort(arr, pivot + 1, endIndex);
        }
    }

    private static int randomizePartiton(int[] arr, int startIndex, int endIndex) {
        int randomIndex = (int) Math.floor((Math.random() * (endIndex - startIndex + 1) + startIndex));
        swap(arr, randomIndex, endIndex);
        return partition(arr, startIndex, endIndex);
    }

    private static int partition(int arr[], int startIndex, int endIndex) {
        // Randomize the pivot.

        int randomIndex = (int) Math.floor((Math.random() * (endIndex - startIndex + 1) + startIndex));
        swap(arr, randomIndex, endIndex);

        int pivotValue = arr[endIndex];
        int pivotIndex = startIndex;
        for (int i = startIndex; i < endIndex; i++) {
            if (arr[i] < pivotValue) {
                swap(arr, i, pivotIndex);
                pivotIndex++;
            }
        }
        swap(arr, pivotIndex, endIndex);

        return pivotIndex;
    }

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

    public void printArr(int arr[]) {
        // for (int val : arr)
        // System.out.print(val + " ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
            if ((i + 1) % 10 == 0)
                System.out.println();
        }
        System.out.println();
    }

    @Test
    public void test() {

        // selectSort time test.
        long start = System.currentTimeMillis();
        Random random = new Random();
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++)
            arr[i] = random.nextInt(100000);
        // printArr(arr);
        selectSort(arr);
        // printArr(arr);
        long end = System.currentTimeMillis();
        System.out.println("Select Sort -- time taken is: " + (end - start) + "ms");

        // insertSort time test
        start = System.currentTimeMillis();
        arr = new int[100000];
        for (int i = 0; i < arr.length; i++)
            arr[i] = random.nextInt(100000);
        // printArr(arr);
        insertSort(arr);
        // printArr(arr);
        end = System.currentTimeMillis();
        System.out.println("Insert Sort -- time taken is: " + (end - start) + "ms");

        // bubbleSort time test
        start = System.currentTimeMillis();
        arr = new int[100000];
        for (int i = 0; i < arr.length; i++)
            arr[i] = random.nextInt(100000);
        // printArr(arr);
        bubbleSort(arr);
        // printArr(arr);
        end = System.currentTimeMillis();
        System.out.println("Bubble Sort -- time taken is: " + (end - start) + "ms");

        // mergeSort time test
        start = System.currentTimeMillis();
        arr = new int[100000];
        for (int i = 0; i < arr.length; i++)
            arr[i] = random.nextInt(100000);
        // printArr(arr);
        mergeSort(arr);
        // printArr(arr);
        end = System.currentTimeMillis();
        System.out.println("Merge Sort -- time taken is: " + (end - start) + "ms");

        // quickSort time test
        start = System.currentTimeMillis();
        arr = new int[100000];
        for (int i = 0; i < arr.length; i++)
            arr[i] = random.nextInt(100000);
        // printArr(arr);
        quickSort(arr);
        // printArr(arr);
        end = System.currentTimeMillis();
        System.out.println("Quick Sort -- time taken is: " + (end - start) + "ms");

    }

    @Test
    public void test1() {
        Random random = new Random();
        int[] arr = new int[100];
        for (int i = 0; i < 100; i++) {
            arr[i] = random.nextInt(100);
        }
        printArr(arr);
        quickSort(arr);
        printArr(arr);
    }
}

//Running result:
Select Sort -- time taken is: 2585ms
Insert Sort -- time taken is: 2936ms
Bubble Sort -- time taken is: 14472ms
Merge Sort -- time taken is: 53ms
Quick Sort -- time taken is: 15ms
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值