快排模板

void quick_sort(int* Num, int L, int R)
{
    if (L >= R)return;
    swap(Num[L], Num[L + R >> 1]);
    int i = L; int j = R;
    int Temp = Num[L];
    while (i < j)
    {
            for (; Num[j] >= Temp&&i<j; j--);
            for (; Num[i] <= Temp&&i<j; i++);
            swap(Num[i], Num[j]);
    }
    swap(Num[i], Num[L]);
    quick_sort(Num, L, i -1);
    quick_sort(Num, i + 1, R);
}

非常的精简,非常的美味

在加另外一种快排模板,与上面的不同的是,下面的快速排序模板在一次排序后并不会确定一个数的最终位置,而上面的会,但是下面的会更快

 

void quick_sort(int q[], int L, int R)
{
    if (L >= R)return;
    int pivot = q[L + R>> 1];
    int l = L-1; int r = R+1;//设置成两边,因为下面的do while循环的逻辑是先移动再比较,故第一次比较前就会分别向后向前移动一位
    while (l < r)
    {
        do l++; while (q[l] < pivot);
        do r--; while (q[r] > pivot);//这里遇到等于也会停止
        if (l < r)swap(q[l], q[r]);
    }
    quick_sort(q, L, r);
    quick_sort(q, r+1, R);//关于使用l还是r来当作分界点,可以这样想
}
当排序后,l和r的相对位置只有两种情况,一种是l==r,另一种是l在r的右侧(即彼此恰好掠过)
因此综合上述,分界方法有上述的r分界,而l分界则是(L,l-1)左半边,(l,R)右半边
我们根据主元的取法,(L+R)/2,相当于L+R的向上取整,也就是说会取到接近左边界的中间点,因此当出现-1操作也就是上述的l-1,容易发生越界操作,因此只能使用r分界
同理 L+R+1>>1相当于L+R的向下取整,也就说会取到接近右半边,故+1操作也就是r+1易发生越界,因此只能使用l分界

 

 

 

附加三元取中的模板方法

int Get_pivot(int *Num,int L,int R)
{
    int mid = (L + R) / 2;
    if (Num[L] > Num[R])
        swap(Num[L], Num[R]);//确保最左边大于最右边
    if (Num[R] > Num[mid])
        swap(Num[R], Num[mid]);
    if (Num[L] > Num[mid])
        swap(Num[L], Num[mid]);
三轮过后会使得中间值交换到mid位置
return mid; }

 

posted @ 2023-04-22 23:20  凪风sama  阅读(19)  评论(0编辑  收藏  举报