Plantilla de combinación y ordenación rápida

Plantilla de fila rápida

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);  	
    **/
}

Nota: Hay un pequeño detalle en la selección de intervalos recursivos. Si elige la notación 2, entonces x no puede seleccionar el extremo izquierdo del intervalo. ¿Por qué sucede esto? Considere un caso extremo como sigue: 3, 6, 4, 7, 9, 8; en este momento, el puntero izquierdo no se moverá, y cuando se realiza la llamada recursiva, todavía se obtiene el intervalo completo, lo que resulta en un bucle sin fin . De la misma forma, cuando se adopta la redacción, no se puede llevar x al extremo derecho del intervalo.
Para las posiciones de lp y rp después de una división: si el valor de división seleccionado es impar, entonces lp y rp coinciden, si el valor de división seleccionado es un valor par e impar, entonces rp se ubica en la posición antes de lp.

Ejemplo:
 
solución de portal :

#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;
}

 

Combinar plantilla

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];
}

Ejemplo:
 
solución de portal :

#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;
}

Supongo que te gusta

Origin blog.csdn.net/PBomb/article/details/107403107
Recomendado
Clasificación