java代码实现几种简单排序算法

文章会不断的更新,有问题可以留言讨论,文章中有不对的地方欢迎大佬些及时指正,以免文章照成误人子弟的不良后果


前言

在学习一个东西前,我觉得首先明确学习目标是非常重要的,如果目标不明确,容易造成三分钟的热情,过了这几分钟兴趣就慢慢的淡了,下次在想起这个东西就不知是猴年马月了。因此我认为在学习一个东西前,我们有必要花些时间细细研究我们学习的目标,以及该学习到何种程度。 对于算法,我想作为一个程序员可能大家都大概了解其重要性,但是如果只是大概了解而能不深入理解的话,我相信这也终将成为我们不断晋升的一大阻碍,虽然以前上大学的时候,我没能真正明白数据结构和算法的重要性体现在哪儿,甚至在做了一段时间的android开发以后,还在保有我只是一个客户端开发,算法没有那么重要的心态,但是在工作中不断的深入学习之后,发现了很多时候不好的算法常常也会导致卡顿,不好的数据结构常常浪费空间的同时,也不一定带来更快的速度,现在也越来越体现到了算法和数据结果的重要性,因此我希望看到这篇文章的年轻程序员们,如果以后还想继续做一个IT工作者,一定要好好学习数据结构与算法。 本片文章介绍几种基本排序算法,及通过实验数据来展示各种算法的优缺点

提示:以下是本篇文章正文内容,下面案例可供参考

一、冒泡排序

排序思路:通过对比和交换两个相邻元素,确保两个对比元素较大的在后,较小的在前,这样一趟对比所有相邻元素就能找到最大元素,依次就能找到大小顺序为1、2、…、n的元素

代码如下(示例):

    public static void maoPaoSort(int[] arr) {
    
    
        for (int i = 0; i < arr.length - 1; i++) {
    
    
            for (int j = 1; j < arr.length - i; j++) {
    
    
                if (arr[j - 1] > arr[j]) {
    
    
                    int t = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = t;
                }
            }
        }
    }

二、选择排序

排序思路:通过n次循环,找出当轮循环中最小(最大)的数,并把它与序列中的第一(最后)位数交换
代码如下(示例):

public static void selectSort(int[] arr) {
    
    
        for (int i = 0; i < arr.length; i++) {
    
    
            int smallestIndex = i;
            for (int j = i; j < arr.length; j++) {
    
    
                if (arr[smallestIndex] > arr[j]) {
    
    
                    smallestIndex = j;
                }
            }
            if (smallestIndex != i) {
    
    
                int t = arr[smallestIndex];
                arr[smallestIndex] = arr[i];
                arr[i] = t;
            }
        }
    }

三、插入排序

代码如下(示例):
public static void insertSort(int[] arr) {
    
    
        for (int i = 1; i < arr.length; i++) {
    
    
            int t = arr[i];
            int j = i;
            while (j > 0 && arr[j - 1] > t) {
    
    
                arr[j] = arr[j - 1];
                j--;
            }
            arr[j] = t;
        }
    }

四、快速排序

代码如下(示例):

private static void quickSort(int[] arr, final int start, final int end) {
    
    
        if (start > end) {
    
    
            return;
        }
        int l = start;
        int r = end;
        int flag = l;

        while (l < r) {
    
    
            while (arr[r] >= arr[flag] && l < r) {
    
    
                r--;
            }
            if (arr[flag] > arr[r]) {
    
    
                int t = arr[flag];
                arr[flag] = arr[r];
                arr[r] = t;
                flag = r;
            }

            while (arr[l] <= arr[flag] && l < r) {
    
    
                l++;
            }
            if (arr[flag] < arr[l]) {
    
    
                int t = arr[flag];
                arr[flag] = arr[l];
                arr[l] = t;
                flag = l;
            }
        }
        sort(arr, start, l - 1);
        sort(arr, l + 1, end);
    }

五、希尔排序

代码如下(示例):

 public static void shellSort(int[] arr) {
    
    
        for (int dk = arr.length / 2; dk > 0; dk /= 2) {
    
    
            for (int i = dk; i < arr.length; i++) {
    
    
                int t = arr[i];
                int j = i;
                while (j >= dk && arr[j - dk] > t) {
    
    
                    arr[j] = arr[j - dk];
                    j -= dk;
                }
                arr[j] = t;
            }
        }
    }

六、堆排序

代码如下(示例):

public static void heapSort(int[] arr) {
    
    
        buildMaxHeap(arr);
        for (int i = arr.length - 1; i >= 0; i--) {
    
    
            swap(arr, 0, i);
            forHeapify(arr, 0, i);
        }
    }
    private static void buildMaxHeap(int[] arr) {
    
    
        for (int i = (arr.length >> 1) - 1; i >= 0; i--) {
    
    
            forHeapify(arr, i, arr.length);
        }
    }
    private static void reHeapify(int[] arr, int i, int length) {
    
    //递归实现
        int left = (i << 1) + 1;
        int largestIndex = i;
        if ((left + 1) < length && arr[left + 1] > arr[largestIndex]) {
    
    
            largestIndex = left + 1;
        }
        if (left < length && arr[left] > arr[largestIndex]) {
    
    
            largestIndex = left;
        }
        if (largestIndex != i) {
    
    
            swap(arr, largestIndex, i);
            reHeapify(arr, largestIndex, length);
        }
    }
    private static void forHeapify(int[] arr, int i, int length) {
    
    //循环实现
        int left = (i << 1) + 1;
        int largestIndex = i;
        while(left<length) {
    
    
            if ((left + 1) < length && arr[left + 1] > arr[largestIndex]) {
    
    
                largestIndex = left + 1;
            }
            if (left < length && arr[left] > arr[largestIndex]) {
    
    
                largestIndex = left;
            }
            if (largestIndex != i) {
    
    
                swap(arr, largestIndex, i);
                left = largestIndex*2 +1;
                i = largestIndex;
            } else {
    
    
                break;
            }
        }
    }
    private static void swap(int[] arr, int i, int j) {
    
    
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

测试数据结果分析

我们分别对上面集中排序进行两组测试,第一次随机产生5000个小于50000的数,每个排序测试10次,第二次对50000个进行10次

public class SortTest {
    
    
    private int[] arr;
    @Before
    public void setUp() {
    
    
        arr = new int[50000];
        for (int i = 0; i < arr.length; i++) {
    
    
            arr[i] = random.nextInt(50000);
        }
    }
    @Test
    public void maopaoSortTest() {
    
    
        //第一次length为5000 25ms 23ms 23ms 26ms 23ms 22ms 25ms 23ms 23ms 24ms
        //第二次length为50000 3195ms 3123ms 3150ms 3191ms 3109ms 3139ms 3159ms 3186ms 3186ms 3134ms
        long start = System.currentTimeMillis();
        System.out.println("maopaoSortTest before arr = " + Arrays.toString(arr));
        maoPaoSort(arr);
        System.out.println("maopaoSortTest after arr = " + Arrays.toString(arr));
        System.out.println("maopaoSortTest time = " + (System.currentTimeMillis() - start));
    }
    @Test
    public void selectSortTest() {
    
    
        //第一次length为5000 14ms 15ms 15ms 13ms 13ms 15ms 14ms 15ms 15ms 13ms
        //第二次length为50000 785ms 810ms 774ms 789ms 785ms 797ms 814ms 772ms 807ms 787ms
        long start = System.currentTimeMillis();
        System.out.println("selectSortTest before arr = " + Arrays.toString(arr));
        selectSort(arr);
        System.out.println("selectSortTest after arr = " + Arrays.toString(arr));
        System.out.println("selectSortTest time = " + (System.currentTimeMillis() - start));
    }
    @Test
    public void insertSortTest() {
    
    
        //第一次length为5000 9ms 12ms 11ms 9ms 11ms 11ms 10ms 10ms 9ms 10ms
        //第二次length为50000 200ms 203ms 199ms 217ms 200ms 213ms 196ms 207ms 203ms 202ms
        long start = System.currentTimeMillis();
        System.out.println("insertSortTest before arr = " + Arrays.toString(arr));
        insertSort(arr);
        System.out.println("insertSortTest after arr = " + Arrays.toString(arr));
        System.out.println("insertSortTest time = " + (System.currentTimeMillis() - start));
    }
    @Test
    public void quickSortTest() {
    
    
        //第一次length为5000 5ms 5ms 5ms 5ms 5ms 5ms 5ms 5ms 5ms 4ms
        //第二次length为50000 47ms 33ms 29ms 38ms 53ms 39ms 41ms 31ms 38ms 42ms
        long start = System.currentTimeMillis();
        System.out.println("quickSortTest before arr = " + Arrays.toString(arr));
        quickSort(arr, 0, arr.length);
        System.out.println("quickSortTest after arr = " + Arrays.toString(arr));
        System.out.println("quickSortTest time = " + (System.currentTimeMillis() - start));
    }
    @Test
    public void shellSortTest() {
    
    
        //第一次length为5000 5ms 6ms 6ms 6ms 6ms 6ms 6ms 7ms 6ms 6ms
        //第二次length为50000 30ms 29ms 31ms 32ms 30ms 29ms 32ms 35ms 33ms 31ms
        long start = System.currentTimeMillis();
        System.out.println("shellSortTest before arr = " + Arrays.toString(arr));
        shellSort(arr);
        System.out.println("shellSortTest after arr = " + Arrays.toString(arr));
        System.out.println("shellSortTest time = " + (System.currentTimeMillis() - start));
    }
    @Test
    public void heapSortTest() {
    
    
        //第一次length为5000 4ms 5ms 5ms 4ms 5ms 4ms 5ms 7ms 5ms 6ms
        //第二次length为50000 31ms 32ms 30ms 29ms 31ms 30ms 32ms 37ms 30ms 30ms
        long start = System.currentTimeMillis();
        System.out.println("heapSortTest before arr = " + Arrays.toString(arr));
        heapSort(arr);
        System.out.println("heapSortTest after arr = " + Arrays.toString(arr));
        System.out.println("heapSortTest time = " + (System.currentTimeMillis() - start));
    }
}

从测试数据可以看出冒泡排序效率最低,其次分别为选择排序和插入排序,而快速排序在数据量为50000时效率开始明显低于希尔和堆排序,而希尔排序在数据量为5000时效率明显则低于快速排序,两次数据综合来看快速排序,希尔排序,堆排序都不稳定

猜你喜欢

转载自blog.csdn.net/weixin_38358978/article/details/114746524