排序

学习小tip:课上理解主要思想,课下背过模板、完成课后习题,每题写3-5遍。

快速排序是不稳定的,归并排序是稳定的。

稳定是指如果一个整数序列中有两个相同的数,排序后它们的位置一定不发生变化,则该排序是稳定的。

简便版排序c++库algorithm中的sort(q,q+n)。

快速排序,基于分治。一个数来分左边和右边。

基本步骤:

1. 确定分界点:q[l],q[r],q[(l+r)/2],随机点;

2. 调整区间:左边都小于等于分界值,右边都大于等于分界值;

3. 用两个“指针”i和j,指向左右两端;

4. 递归处理左右两端。

 

注意:凡是涉及到边界问题的,建议背过一个模板,因为模板都是经历过千锤百炼的。

快速排序算法模板:

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

小细节:如果取x=q[L],则quick_sort(q,l,j)中的j不能改为i-1,否则会出现边界问题(死循环,如数据1,2);

 

归并排序,基于分治。

1. 确定分界点 mid=(l+r)/ 2;
2. 递归排序左边和右边;
3. 归并,合二为一。

归并排序模板:

void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int mid = l + r >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];

    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

 

posted @ 2021-03-31 21:28  esico  阅读(11)  评论(0)    收藏  举报