快排与归并模板

快排摸板

void quickSort(int nums[], int l, int r)
{
    
    
    if(l >= r) return;

    int x = nums[l];
    int lp = l-1, rp = r+1; // 定义左右两指针

    while(lp < rp)
    {
    
    
        do lp++; while (q[lp] < x);
        do rp--; while (q[rp] > x);

        if (lp < rp) swap(q[lp], q[rp]);
    }
	//写法一:
    quickSort(nums, l, rp);
    quickSort(nums, rp+1, r);
    /**
   	写法二:
    quickSort(nums, r, lp-1);
    quickSort(nums, lp, r);  	
    **/
}

注意:递归的区间选取有个小细节,若选择写法二,则x不能选择区间左端点,为什么会出现这种情况呢?以下考虑一种极端情况:3,6,4,7,9,8 ;此时左指针不会发生移动,当递归调用时,仍得到整个区间,造成死循环。同理采用写法一时,x不能取到区间右端点。
对于一次划分后lp和rp的位置: 若选取的划分值为奇数个,则lp与rp重合,若选取的划分值为奇数个值为偶数个,则rp位于lp前一个位置。

例题:传送门
 
题解:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;
const int N = 100010;
int nums[N], n;

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

    int x = q[rand()%(r-l+1)+l]; //防止特殊数据,随机选择区间内的点
    int lp = l-1, rp = r+1;

    while(lp < rp)
    {
    
    
        do lp++; while (q[lp] < x);
        do rp--; while (q[rp] > x);

        if (lp < rp) swap(q[lp], q[rp]);

    }

    quickSort(nums, l, rp);
    quickSort(nums, rp+1, r);
}


int main ()
{
    
    
    srand((unsigned int)time(NULL));
    cin >> n;
    for (int i = 0; i < n; i++) cin >> nums[i];

    quickSort(nums, 0, n-1);

    for(int i = 0; i < n; i++)
    {
    
    
        cout << nums[i];
        if(i == n-1) cout << endl;
        else cout << " ";
    }

    return 0;
}

归并模板

void mergeSort(int q[], int l, int r)
{
    
    
    if (l >= r) return;
    
    int mid = (l + r) >> 1;
    
    mergeSort(q, l, mid), mergeSort(q, mid+1, r);
    
    // 利用临时数组temp进行合并
    int k = 0, f = l, s = mid + 1;// f为左区间的指针,s为右区间的指针
    while (f <= mid && s <= r)
    {
    
    
        if(q[f] <= q[s]) temp[k++] = q[f++];
        else temp[k++] = q[s++];
    }
    
    while (f <= mid) temp[k++] = q[f++];
    while (s <= r) temp[k++] = q[s++];
    
    for(int i = l, j = 0; i <= r; i++, j++) q[i] = temp[j];
}

例题:传送门
 
题解:

#include <iostream>
using namespace std;

const int N = 100010;

int nums[N], temp[N], n;

void mergeSort(int q[], int l, int r)
{
    
    
    if (l >= r) return;
    
    int mid = (l + r) >> 1;
    
    mergeSort(q, l, mid), mergeSort(q, mid+1, r);
    
    int k = 0, f = l, s = mid + 1;
    while (f <= mid && s <= r)
    {
    
    
        if(q[f] <= q[s]) temp[k++] = q[f++];
        else temp[k++] = q[s++];
    }
    
    while (f <= mid) temp[k++] = q[f++];
    while (s <= r) temp[k++] = q[s++];
    
    for(int i = l, j = 0; i <= r; i++, j++) q[i] = temp[j];

}

int main()
{
    
    
    cin >> n;
    for (int i = 0; i < n; i++) cin >> nums[i];
    
    mergeSort(nums, 0, n-1);
    
    for (int i = 0; i < n; i++) cout << nums[i] << " ";
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/PBomb/article/details/107403107