快排寄了一个点

P1923 【深基9.例4】求第 k 小的数

milk2715093695 @ 2023-11-13 15:39:09

#include <stdio.h>

void Swap(long long *a, long long *b) {
    long long temp = *a;
    *a = *b;
    *b = temp;
}

void InsertSort(long long arr[], int low, int high) {
    for (int i = low + 1; i <= high; ++i) {
        long long key = arr[i];
        int j = i - 1;

        // 将比 key 大的元素向右移动
        while (j >= low && arr[j] > key) {
            arr[j + 1] = arr[j];
            --j;
        }

        // 将 key 插入到合适的位置
        arr[j + 1] = key;
    }
}

long long NumberOfThree(long long arr[], int low, int high) {
    int mid = low + ((high - low) >> 1);//右移相当于除以2

    if (arr[mid] > arr[high]) {
        Swap(&arr[mid], &arr[high]);
    } if (arr[low] > arr[high]) {
        Swap(&arr[low], &arr[high]);
    } if (arr[mid] > arr[low]) {
        Swap(&arr[mid], &arr[low]);
    }
    //此时,arr[mid] <= arr[low] <= arr[high]
    return arr[low];
}

void QSort(long long arr[], int low, int high) {
    int first = low;
    int last = high;

    int left = low;
    int right = high;

    int leftLen = 0;
    int rightLen = 0;

    if (high - low + 1 < 10)
    {
        InsertSort(arr, low, high);
        return;
    }

    //一次分割
    long long key = NumberOfThree(arr, low, high);//使用三数取中选择枢轴

    while(low < high) {
        while(high > low && arr[high] >= key) {
            if (arr[high] == key) {//处理相等元素
                Swap(&arr[right], &arr[high]);
                right--;
                rightLen++;
            }
            high--;
        }
        arr[low] = arr[high];
        while(high > low && arr[low] <= key) {
            if (arr[low] == key) {
                Swap(&arr[left], &arr[low]);
                left++;
                leftLen++;
            }
            low++;
        }
        arr[high] = arr[low];
    }
    arr[low] = key;

    //一次快排结束,把与基准相等的元素移到基准周围
    int i = low - 1;
    int j = first;
    while(j < left && arr[i] != key) {
        Swap(&arr[i], &arr[j]);
        i--;
        j++;
    }
    i = low + 1;
    j = last;
    while(j > right && arr[i] != key) {
        Swap(&arr[i], &arr[j]);
        i++;
        j--;
    }
        QSort(arr, first, low - 1 - leftLen);
        QSort(arr, low + 1 + rightLen, last);
}

long long arr[5000000];

int main(void) {
    int n, k;
    scanf("%d %d", &n, &k);

    for (int i = 0; i < n; ++i) {
        scanf("%lld", &arr[i]);
    }

    QSort(arr, 0, n - 1);

    printf("%lld", arr[k]);

    return 0;
}

by InversionShadow @ 2023-11-13 15:43:57

快排是可以卡到 n^2


by milk2715093695 @ 2023-11-13 15:49:31

@ydq1101 是的,但是已经尽量优化过了,感觉已经不是那么容易卡到n^2的了,所以说快排一定是不行的吗?


by SSqwq_ @ 2023-11-13 15:51:58

@milk2715093695 std::sort


by 小木虫 @ 2023-11-13 15:56:01

@milk2715093695 key改成mt19937生成的随机数


by wxh666 @ 2023-11-13 16:03:35

@milk2715093695 sort启动!


by milk2715093695 @ 2023-11-14 16:32:30

最后还是靠被改的丧心病狂的快排过了...


by Feynman5210 @ 2023-12-23 16:10:53

我试验了,最后一个点958ms。卡一下常。


|