美文网首页
JAVA数据结构和算法——简单排序

JAVA数据结构和算法——简单排序

作者: 往昔負流年 | 来源:发表于2018-08-24 17:57 被阅读0次

    冒泡排序

        /**
         * 冒泡排序
         * 需要N*(N-1)/2约等于N*N/2次比较,因为满足条件才交换所以交换的次数少于比较的次数
         * 如果数据是随机的那么大概一半数据需要交换,则交换次数为N*N/4。
         * 交换和比较操作次数都和N*N成正比。常数不算在大O表示法中可以忽悠2和4,
         * 所以冒泡排序运行需要O(N*N)时间级别。
         * 不变性:out右边的数据总是有序的
         * 个人理解:N*N/2次比较+交换次数为N*N/4
         * @param arr
         */
        public void bubbleSort(int[] arr) {
            int length = arr.length;
            for(int out = length-1; out > 0; out--) {
                //下标大于out的数据是已经排好序了的所以没有必要比较交换
                for(int in = 0; in < out; in++) {
                    //比较
                    if(arr[in] > arr[in+1]) {
                        //如果满足左边大于右边则交换
                        int temp = arr[in];
                        arr[in] = arr[in+1];
                        arr[in+1] = temp;
                    }
                }
            }
        }
    

    选择排序

        /**
         * 选择排序
         * 选择排序和冒泡排序执行了相同次数的比较:N*(N-1)/2。
         * N值很大时,比较次数是主要的,所以结论是选择排序和冒泡排序一样运行了O(N*N)时间。
         * 但是选择排序无疑更快,因为他进行交换次数少的多(O(N))。
         * 当N值较小时,特别是如果交换时间级比比较时间级大得多时,选择排序实际上是相当快的。
         * 不变性:out左边的数据总是有序的
         * 个人理解:其实是N*(N-1)/2次比较+(O(N))次交换+N*(N-1)/4复制
         * @param arr
         */
        public void selectionSort(int[] arr) {
            for(int out = 0; out < arr.length - 1; out++) {
                //寻找最小值的下标
                int min = out;
                for(int in = out + 1; in < arr.length; in++) {
                    if(arr[in] < arr[min]) {
                       //其实按照个人理解这个需要N*(N-1)/4复制
                        min = in;
                    }
                }
                //把最小放在最左边
                int temp = arr[min];
                arr[min] = arr[out];
                arr[out] = temp;
            }
        }
    

    插入排序

        /**
         * 插入排序
         * 不变性:在每趟结束结束时,在讲temp位置的项插入后,比out变量下标小的数据项都是局部有序的。
         * 效率:在第一趟排序中最多比较一次,第二趟最多比较两次,以此类推最后一躺最多比较N-1次。
         * 因此1+2+3+...+N-1 = N*(N-1)/2,然而因为在每一趟排序发现插入点之前,平均只有全体数据项的一半
         * 真的进行了比较,我们除以2得到N*(N-1)/4.
         * 复制次数大致等于比较次数。然后一次复制与一次交换的时间耗费不同,所以相对于随机数据,这个算法比冒泡排序快一倍,
         * 比选择排序略快。于其他简单排序一样对于随机顺序的数据进行插入排序也需要O(N*N)的时间级。
         * 对于已经有序或基本有序的数据来说,插入排序要好得多。
         * 个人理解:N*(N-1)/4比较+N*(N-1)/4次复制+N次复制
         * @param arr
         */
        public void insertionSort(int[] arr) {
            for(int out = 1; out < arr.length; out++) {
                int temp = arr[out];
                int in = out;
                while (in > 0 && arr[in-1] >= temp) {
                     //个人理解这儿是N*(N-1)/4次复制
                    arr[in] = arr[in-1];
                    --in;
                }
                 //个人理解这儿是N次复制
                arr[in] = temp;
    
            }
        }
    

    排序算法的选择

    除非手边没有算法书可参考,一般情况几乎不太用冒泡排序。选择排序虽然把交换次数降到最低,但比较次数依然很大。当数据量很小,并且交换数据相对于比较数据更加耗时的情况下可以用选择排序。在大多数的情况下假设数据量比较小,或者基本有序时,插入排序是三种简单排序中最好的选择。对于更大数据量的排序来说,快速排序通常是更快的方法。
    除了在速度方面比较排序算法外,还有一个衡量标准就是算法需要的内存空间多大。这三种算法都除了数组外几乎不需要其他的内存空间。所有排序算法都需要一个额外的变量来暂时存储变换时的数据项。

    相关文章

      网友评论

          本文标题:JAVA数据结构和算法——简单排序

          本文链接:https://www.haomeiwen.com/subject/auxcbftx.html