• 【归并排序/快排/堆排序】912. 排序数组


    力扣连接:. - 力扣(LeetCode)

    归并排序

    对左右子集合分别排序,然后合并两个有序数组

    1. class Solution {
    2. int[] nums;
    3. public int[] sortArray(int[] nums) {
    4. this.nums = nums;
    5. return sort(0, nums.length-1);
    6. }
    7. int[] sort(int st, int ed) {
    8. if(st == ed) {
    9. return new int[]{nums[st]};
    10. }
    11. //对左右分别排序
    12. int m = st + (ed-st)/2;
    13. int[] leftArr = sort(st, m);
    14. int[] rightArr = sort(m+1, ed);
    15. //合并两个有序数组
    16. int[] newArr = new int[ed-st+1];
    17. int i=0,j=0,k=0;
    18. while(i
    19. if(leftArr[i]
    20. newArr[k++]=leftArr[i++];
    21. }else{
    22. newArr[k++]=rightArr[j++];
    23. }
    24. }
    25. while(i
    26. while(j
    27. return newArr;
    28. }
    29. }

    快排

    每次任意指定一个数作为标杆,小于标杆的放左边,大于标杆的放右边,对左右子数组重复这个流程

    时间复杂度:O(n log n)

    空间复杂度:O(n)

    1. class Solution {
    2. int[] nums;
    3. public int[] sortArray(int[] nums) {
    4. this.nums = nums;
    5. sort(0, nums.length - 1);
    6. return nums;
    7. }
    8. void sort(int st, int ed) {
    9. if (st >= ed)
    10. return;
    11. int p = st, l = st, r = ed;
    12. while (l < r) {
    13. // r指向第一个小于等于nums[p]的,注意这和下个while顺序不能随便换,要保证l和r最后指向小于等于nums[p]的地方
    14. while (l < r && nums[r] > nums[p]) r--;
    15. // l指向第一个大于nums[p]的
    16. while (l < r && nums[l] <= nums[p]) l++;
    17. swap(l, r);
    18. }
    19. swap(p, l);
    20. sort(st, l - 1);
    21. sort(l + 1, ed);
    22. }
    23. void swap(int i, int j) {
    24. int temp = nums[i];
    25. nums[i] = nums[j];
    26. nums[j] = temp;
    27. }
    28. }

    堆排序

    时间复杂度:O(nlogn)

    视频讲解:排序算法:堆排序【图解+代码】_哔哩哔哩_bilibili

    大顶堆:父节点比两个子节点都要大

    下标规律:

    节点 i 的父节点:(i-1)/2

    节点 i 的左子节点:i*2+1

    节点i的右子节点:(i+1)*2

    维护大顶堆:从下往上,第一个有孩子节点的节点开始,取根节点、左孩子、右孩子之间的最大值 换到根节点处

    排序:堆顶的元素一定是最大的,每次将堆顶元素放到尾部,然后剩下元素再次维护大顶堆,重复

    1. class Solution {
    2. int[] nums;
    3. public int[] sortArray(int[] nums) {
    4. this.nums = nums;
    5. int len = nums.length;
    6. sort(len);
    7. return nums;
    8. }
    9. void sort(int len) {
    10. //建堆
    11. for(int i= len/2-1;i>=0;i--) {
    12. heapify(len, i);
    13. }
    14. //排序
    15. for(int i=len-1;i>0;i--) {
    16. swap(i, 0);
    17. //i以后的数是已经排序好的
    18. heapify(i, 0);
    19. }
    20. }
    21. //i: 待维护的节点下标
    22. //len: 参与维护大顶堆的数组长度
    23. void heapify(int len, int i) {
    24. int biggest = i;
    25. int left = i*2+1;
    26. int right = (i+1)*2;
    27. //len用来约束递归终止条件
    28. if(left
    29. biggest = left;
    30. }
    31. if(right
    32. biggest = right;
    33. }
    34. if(biggest != i){
    35. swap(biggest, i);
    36. heapify(len, biggest);
    37. }
    38. }
    39. void swap(int i, int j) {
    40. int temp = nums[i];
    41. nums[i] = nums[j];
    42. nums[j] = temp;
    43. }
    44. }

  • 相关阅读:
    图计算发展简史(上)
    消息治理,到底需要治理哪些内容?
    spring-security 过滤器
    浏览器LocalStorage和SharedWorker跨标签页通信-连载2
    vue实战入门后台篇六:springboot+mybatis实现网站后台-前端登录功能对接
    FIFO控制器设计——日常学习
    Sqoop的安装与配置 第1关:Sqoop的安装与配置
    Spring事务管理 | 数据库连接池流程原理分析
    T-SQL——数字辅助表
    中缀表达式 - 栈实现综合计算器
  • 原文地址:https://blog.csdn.net/m0_63530048/article/details/140957757