美文网首页
思路|堆&归并

思路|堆&归并

作者: doraTrager | 来源:发表于2019-12-20 13:35 被阅读0次

学习笔记,可能有些谬误,请批判性阅读。

k个有序列表的全局排序。

思路1:两两归并,直至第k个

思路2:建立大小为k的最小堆,进行归并。

求数组的逆序对

参考[1],实际就是归并排序,在归并排序的过程中,如果有逆序对出现,进行累加,累加值为右子序列的剩余长度。需要注意的是,从后往前归并。
哎,我那脑袋不好使的时候写不出来的归并排序啊。

void merge(int* a, int* b, int l, int m, int r, int& reverse_count){
    // a是原始数组,a[l...m],a[m+1...r]分别是左右两个子序列
    // b是个辅助数组,用来暂存排归并后的序列。
    // reverse_count用来存储逆序对数目
    // 因为比较逆序,左边的数大于右边的数视为一个逆序。
    // 因此从后往前遍历
    int i = m;
    int j = r;
    int k = r;
    while(k >= 0){
        if(i < l){ // 左子序列遍历完成
            b[k--] = a[j--];
        }else if(j < m + 1){ // 右子序列遍历完成
            b[k--] = a[i--];

        }else{
            if(a[i] > a[j]){ // 取较大值放入b,另外,此时构成了逆序
                b[k--] = a[i--];
                reverse_count += j - m; // 右子序列剩余多少个元素,就有多少个逆序对。
            }else{
                b[k--] = a[j--];// 若a[i] <= b[j],不构成逆序
            }
        }
    }
    for(k = l; k <= r; k++){
        a[k] = b[k];
    }
}

void merge_sort_helper(int* a, int* b, int l, int r, int& reverse_count){
    if(l >= r){
        return;
    }
    mid = (l + r) / 2;
    merge_sort_helper(a, b, l, mid, reverse_count);
    merge_sort_helper(a, b, mid + 1, r, reverse_count);
    merge(a, b, l, mid, r, reverse_count);
}

int merge_sort(int* a, int n){
    if(n<=1){
        return
    }

    int* b = new int[n];
    int reverse_count = 0;
    merge_sort_helper(a, b, 0, n - 1, reverse_count);
    delete b;
    
    return reverse_count;
}

问题|排序一文中的归并排序基本是一致的,除了细节处为了记录逆序对数做的添加。
又及,这里涉及到引用,可以参考[3] & [4]。

求数组中第k大的数

求数组中前k大的数

求数组中出现次数超过一半的数

参考[2],第二种思路是快排,出现超过一半的数,第n/2大的数一定是这个数,就和「求数组中前k大的数」成了一样的问题。
第一种思路比较牛批。

遍历数组是保存两个值:
一个是数字中的一个数字,另一个是次数。
当遍历到下一个数字的时候,如果下一个数字和之前保存的数字相等,则次数加1;
如果不同,则次数减1;如果次数为零,那么我们需要保存下一个数字,并把次数设置为1。
由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,
那么要找的数字肯定是最后一次把次数设置为1时对应的数字。

求数组中的最大值和最小值

《编程之美》上的问题。依靠分治思想。

参考

[1] https://blog.csdn.net/qq_28081081/article/details/80804781
[2] https://blog.csdn.net/SCS199411/article/details/91462505
[3] https://www.runoob.com/cplusplus/cpp-references.html
[4] https://www.runoob.com/cplusplus/passing-parameters-by-references.html

相关文章

  • 思路|堆&归并

    学习笔记,可能有些谬误,请批判性阅读。 k个有序列表的全局排序。 思路1:两两归并,直至第k个 思路2:建立大小为...

  • 排序算法(五)归并排序

    排序算法(五 )归并排序 1.算法思路  归并排序(Merge-Sort)是一种基于二叉堆及分而治之思想的排序算法...

  • 海量数据处理

    处理海量数据的常规思路 分而治之/Hash映射 + Hash_map统计 + 堆/快速/归并排序 1、海量日志数据...

  • 排序算法

    快排 堆排 归并

  • 归并排序(二路归并排序)

    归并排序的思路 归并排序是通过“归并”操作完成排序的,将两个或者多个有序子表归并成一个子表。归并排序是“分治法”的...

  • 基于左闭右开的乱序数组归并排序 2020-04-24(未经允许,

    归并排序代码模板 递归形式思路:二分nums数组后对nums的归并排序 = 对左侧数组归并排序+对右侧数组归并排序...

  • 经典排序算法系列5-快速排序

    Quick Sort 快速排序 需求 对N个整数升序排序 思路 和归并排序一样,也是用的分治思想,但实现思路和归并...

  • 数据结构 - 归并排序

    归并排序 - 算法思路 归并排序 - 动图演示 时间复杂度 O(nlogn) 代码实现 printVector: ...

  • 归并排序

    归并排序 动图演示 思路分析 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用...

  • python数据结构教程 Day9

    本节重点 归并排序 快速排序 一、归并排序 算法思路: 应用分治策略,是一种递归算法,思路是将数据表持续分裂为两半...

网友评论

      本文标题:思路|堆&归并

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