资讯专栏INFORMATION COLUMN

Sorting

calx / 500人阅读

摘要:是稳定的排序,但是它需要额外的空间,时间复杂度为程序这个同上也是两个步骤,。最坏情况的时间复杂度为但是在实际情况中,通常是排序的最佳选择。就是有序的完全二叉树,所有我们要先根据已有的数组来建立一个。最后由后往前形成一个有序数组。

Bubble Sort就不说了,下面简单总结一个Selection Sort, Insertion Sort, Merge Sort和Quick Sort:

1.Selection Sort:
其实就是每次选出数组中的最小值放在当前位置,然后往后扫,
举例:
(29, 64, 73, 34, 20)
20, (64, 73, 34, 29)
20, 29, (73, 34, 64)
20, 29, 34, (73, 64)
20, 29, 34, 64, (73)
最差情况下的时间复杂度是O(n2).
程序:

public class SelectionSort {
    public static void selectionSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;
            for (int j = i + 1; j < arr.length; j++) {
                min = arr[j] < arr[min] ? j : min;
            }
            int temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {5, 32, 23, 5, 6, 8, 44};
        selectionSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

2.Insertion Sort:
其实就是把每次扫到的这个数,插到前面已经sorted好的数组中去:
举例:
29, 20, 73, 34, 64
(29), 20, 73, 34, 64
(20, 29), 73, 34, 64
(20, 29, 73), 34, 64
(20, 29, 34, 73), 64
(20, 29, 34, 64, 73)
时间复杂度是O(n2).
程序:

public class InsertionSort {
    public static void InsertionSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int index = arr[i], j = i;
            while (j > 0 && arr[j - 1] > index) {
                arr[j] = arr[j - 1];
                j--;
            }
            arr[j] = index;
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {5, 32, 23, 5, 6, 8, 44};
        InsertionSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

3.Merge Sort:
这个sort分两个步骤,divide & merge。我们首先要把这个list分成两个部分,然后对这两个部分sort,然后把sort后的结果merge起来,只要操作就在于merge,最后就得到最终的结果了。Merge sort是稳定的排序,但是它需要额外的空间,时间复杂度为O(nlogn).
程序:

public class MergeSort {
    public static int[] mergeSort(int[] arr) {
        if (arr == null || arr.length == 0 || arr.length == 1) return arr;
        int mid = arr.length / 2;
        int[] left = mergeSort(Arrays.copyOfRange(arr, 0, mid));
        int[] right = mergeSort(Arrays.copyOfRange(arr, mid, arr.length));

        
        return merge(left, right);
        
    }
    
    public static int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        int i = 0, j = 0, k = 0;
        while (i < left.length && j < right.length) {
            if (left[i] < right[j]) {
                result[k++] = left[i++];
            } else {
                result[k++] = right[j++];
            }
        }
        while (i < left.length) {
            result[k++] = left[i++];
        }
        while (j < right.length) {
            result[k++] = right[j++];
        }
        
        return result;
    }
    
    public static void main(String[] args) {
        int[] arr = {5, 32, 23, 5, 6, 8, 44};
        int[] result = mergeSort(arr);
        for (int num : result) {
            System.out.print(num + " ");
        }
    }
}

4.Quick Sort:
这个sort同上也是两个步骤,divide & merge。不同的是,这个在divide的时候做了有用的操作,把所有小于当前值的数放到左边,所有大于当前值的数放到右边,然后merge这两个部分。Quick Sort最坏情况的时间复杂度为O(n2).但是在实际情况中,quick sort通常是排序的最佳选择。
程序:

public class QuickSort {
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    } 
    
    public static void quickSort(int[] arr, int low, int high) {
        if (arr == null || arr.length == 0) return;
        if (low >= high) return;
        
        int mid = low + (high - low) / 2;
        int pivot = arr[mid];
        
        int i = low, j = high - 1;
        while (i <= j) {
            while (arr[i] < pivot) {
                i++;
            }
            while (arr[j] > pivot) {
                j--;
            }
            if (i <= j) {
                swap(arr, i, j);
                i++;
                j--;
            }
        }
        if (low < j) {
            quickSort(arr, low, j);
        }
        if (i < high) {
            quickSort(arr, i, high);
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {5, 32, 23, 5, 6, 8, 44};
        quickSort(arr, 0, arr.length - 1);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

5.Heap Sort
这个排序看似复杂,其实只要把内部原理弄清楚就一点也不难了。heap就是有序的完全二叉树,所有我们要先根据已有的数组来建立一个heap。我们知道完全树的根结点,左子树,右子树满足这样的特点:left = 2 i(root), right = 2 i + 1。所以我们可以利用这一点,将i, left, right这三个点比较大小,取最大的值作为根结点。如果这个最大值原来就是root,那么我们不需要有任何的改动;如果这个最大值原来是子结点,那么从这个子结点往下,我们还需要逐一比较这个子结点的子结点,找到最大值放在这个子结点的位置,依次类推。
建完树之后就是要取点了,最大值我们已经确定在index为0的位置,但是对于left,right我们并不知道哪个大哪个小。所以可以先把这个root所在的最大值与最后一个数交换(将最大值存到最后去),然后再比较开先锋们的大小,大的那个放在根结点处,为当前最大数,依次类推。最后由后往前形成一个有序数组。
程序:

public class HeapSort {
    public static int N;
    //Build a heap
    public static void heapify(int[] arr) {
        N = arr.length - 1;
        //Bottom up, 也只能bottomup,由上往下的话,根结点有时候会不是最优解
        for (int i = N / 2; i >= 0; i--) {
            maxHeap(arr, i);
        }
    }
    //swap the largest element to root
    public static void maxHeap(int[] arr, int i) {
        int left = 2 * i;
        int right = 2 * i + 1;
        int max = i;
        if (left <= N && arr[left] > arr[i]) {
            max = left;
        }
        if (right <= N && arr[right] > arr[max]) {
            max = right;
        }
        if (max != i) {
            swap(arr, i, max);
            maxHeap(arr, max);
        }
    }
    
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    
    public static void heapSort(int[] arr) {
        heapify(arr);
        for (int i = N; i > 0; i--) {
            swap(arr, 0, i);
            N = N - 1;
            maxHeap(arr, 0);
        }
        
    }
    
    public static void main(String[] args) {
        int[] arr = {5, 32, 23, 5, 6, 8, 44};
        heapSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64843.html

相关文章

  • Java - Sorting Algorithms

    Complexity Quicksort Mergesort Heapsort Time Complexity O(nlogn) O(nlogn) O(nlogn) Space Complexity O(1) O(n) Could be O(1) Quicksort Quicksort is s...

    陈江龙 评论0 收藏0
  • JavaScript 排序算法图解(JavaScript sorting algorithms)

    摘要:基础构造函数以下几种排序算法做为方法放在构造函数里。代码图解选择排序选择排序算法是一种原址比较排序算法。它的性能通常比其他的复杂度为的排序算法要好。代码划分过程图解排序没有定义用哪个排序算法,所以浏览器厂商可以自行去实现算法。 基础构造函数 以下几种排序算法做为方法放在构造函数里。 function ArrayList () { var array = []; // 交换位置...

    h9911 评论0 收藏0
  • Google Python Class --- Sorting

    摘要:它直接作用于列表,并且没有返回值。排序时,列表中的元素会通过函数进行处理,并按照返回值进行排序。会按照元素的长度进行升序排列按照元素的小写进行排序后面可以是自定义函数表达式按照返回值排序元组元组是固定尺寸的元素的集合。 showImg(https://segmentfault.com/img/bVB1Wh); 刚才看到一位朋友谈到如何写出高逼格的文章,想了想确实有道理。所以特意弄一张高...

    madthumb 评论0 收藏0
  • PHP函数之array_multisort()

    摘要:函数之说明函数返回排序数组。把每一项按常规顺序排列,不改变类型。把每一项作为字符串来处理,基于当前区域设置可通过进行更改。示例一维多个数组排序结果相同时,排序在的前面多维数组排序结果 PHP函数之array_multisort() array_multisort() 说明: array_multisort() 函数返回排序数组。您可以输入一个或多个数组。函数先对第一个数组进行排序,接...

    RaoMeng 评论0 收藏0
  • 浅谈 python 中的 sorted()与sort()

    摘要:返回值是一个经过排序的可迭代类型,与一样。注一般来说,和可以使用表达式。与的不同在于,是在原位重新排列列表,而是产生一个新的列表。 我们需要对List进行排序,Python提供了两个方法 对给定的List L进行排序,方法1.用List的成员函数sort进行排序方法2.用built-in函数sorted进行排序(从2.4开始) ----------------------------...

    lansheng228 评论0 收藏0
  • 数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting

    摘要:经过一次冒泡排序,最终在无序表中找到一个最大值,第一次冒泡结束。也是我们后面要说的冒泡排序的优化。冒泡排序只执行第一层循环,而不会执行第二层循环。因此冒泡排序的时间复杂度是。 showImg(https://user-gold-cdn.xitu.io/2019/6/19/16b6f986df6880f9?w=640&h=142&f=gif&s=17175);showImg(https:...

    chuyao 评论0 收藏0

发表评论

0条评论

calx

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<