快速排序笔记

写的脑子都抽了,果然实在做不出来还是得问一下ai。
我自己最后又自己写了一下,是这个:

#include<stdio.h>

int p,q,pivot,mid,temp;
int n;
int P[100100];

void quick(int P[100100],int l, int r){
    if(l>=r){
        return;
    }
    p = l;
    q = r;
    mid = (r+l)>>1;
    pivot = P[mid];
    while(p<=q){
        while(P[p] < pivot){
            p++;
        }
        while(P[q] > pivot){
            q--;
        }
        if(p<=q){
            temp = P[p];
            P[p] = P[q];
            P[q] = temp;
            p++,q--;
        }
    }
    quick(P, l, q);
    quick(P, p, r);
}

int main(){
    scanf("%d",&n);
    for(int i = 0; i < n; i++)scanf("%d",&P[i]);
    quick(P,0,n-1);
    for(int i = 0; i < n; i++)printf("%d ",P[i]);
    return 0;
}

总之思路就是,选出一个基准,然后两个指针往中间找,找到比基准大或者小的就停下来,交换,然后继续,直到他们交错,然后又对两边递归。
第k个数就是直接输出就行,这里代码飘了:

#include<stdio.h>


int pivot,p,q,n,mid,temp,k;
int P[100100];

void quick(int P[100100], int l, int r){
    if(l>=r) return;
    mid = (l+r)>>1;
    pivot = P[mid];
    p=l;
    q=r;
    while(p<=q){
        while(P[p]<pivot)p++;
        while(P[q]>pivot)q--;  
        if(p<=q){
            temp = P[p];P[p] = P[q];P[q] = temp;
            p++;q--;
        }
    }
    quick(P,l,q);
    quick(P,p,r);
}

int main(){
    
    scanf("%d %d",&n,&k);
    for(int i = 0; i < n;i++)scanf("%d",&P[i]);
    quick(P, 0, n-1);
    
    printf("%d",P[k-1]);    
    
    return 0;
}

快速排序代码易错点及对比报告

一、引言

在快速排序算法的实现过程中,容易出现多种逻辑错误,导致程序无法正确运行。本报告将对原错误代码与修正后的代码进行逐段对比,详细分析其中的易错点,帮助理解快速排序算法的正确实现逻辑。

二、代码对比与易错点分析

(一)基准值选择与处理

对比项目 原代码(行15-16) 修正后代码(行15-16) 易错点分析
基准值定义 mid = (l+r)>>1;,直接使用 P[mid] 作为基准值,未单独存储 int mid = (l + r) / 2; int pivot = P[mid];,将基准值存储在 pivot 变量中 原代码直接使用数组中的元素作为基准值,在后续交换操作中,P[mid] 的值可能会被改变,导致分区逻辑混乱。而修正后代码将基准值单独存储,避免了基准值在交换过程中被意外修改,保证了分区的正确性

(二)循环逻辑

对比项目 原代码(行19-34) 修正后代码(行19-34) 易错点分析
内层循环条件 while(P[i]<P[mid])while(P[j]>P[mid]),未处理元素等于基准值的情况 while (P[i] < pivot)while (P[j] > pivot),结合外层 if (i <= j) 处理边界情况 原代码在处理元素等于基准值时,没有正确的处理逻辑,可能导致 ij 交叉后继续交换,造成无限循环。修正后代码通过合理设置循环条件和外层判断,确保 ij 不会交叉,避免了无限循环问题
交换操作 交换后直接进行 i++,j--,未判断 ij 的位置关系 交换后使用 if (i <= j) 判断,只有在 ij 未交叉时才进行指针移动 原代码没有对交换后的 ij 位置关系进行判断,可能导致指针越界或错误交换。修正后代码通过判断,保证了指针在正确的范围内移动,避免了错误操作

(三)递归调用

对比项目 原代码(行36-37) 修正后代码(行36-37) 易错点分析
递归区间 quick(P, l, newp);quick(P, newp+1, r);newp 的更新逻辑不完整,可能无法正确确定基准值新位置 quick(P, l, j);quick(P, i, r);,根据 ij 的最终位置确定递归区间 原代码中 newp 的更新逻辑存在缺陷,当 ij 等于基准值索引时,不能准确更新 newp,导致递归区间错误。修正后代码根据 ij 的最终位置确定递归区间,保证了每次递归都能正确划分数据,实现快速排序的功能

三、完整代码对比

(一)原错误代码

#include<stdio.h>

int n;
int P[100100];
int mid;
int i,j;
int temp, newp;

void quick(int P[100100], int l, int r){
    if(l>=r){
        return;
    }
    mid = (l+r)>>1;
    i = l, j = r;
    newp = -1;
    while(i<=j){
        while(P[i]<P[mid]){
            i++;
        }
        while(P[j]>P[mid]){
            j--;
        }
        temp = P[i];
        P[i] = P[j];
        P[j] = temp;
        if(i==mid){
            newp = j;
        }
        if(j==mid){
            newp = i;
        }       
        i++,j--;
    }
    quick(P, l, newp);
    quick(P, newp+1, r);
}

int main(){
    scanf("%d",&n);
    for (int i = 0; i < n; i++) scanf("%d", &P[i]);
    quick(P, 0, n-1);
    for (int i = 0; i < n; i++) printf("%d ", P[i]);
    return 0;
}

(二)修正后代码

#include<stdio.h>

int n;
int P[100100];

void quick(int P[], int l, int r) {
    if (l >= r) {
        return;
    }
    int mid = (l + r) / 2;
    int pivot = P[mid];
    int i = l, j = r;
    
    while (i <= j) {
        while (P[i] < pivot) {
            i++;
        }
        while (P[j] > pivot) {
            j--;
        }
        if (i <= j) {
            int temp = P[i];
            P[i] = P[j];
            P[j] = temp;
            i++;
            j--;
        }
    }
    
    quick(P, l, j);
    quick(P, i, r);
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &P[i]);
    }
    quick(P, 0, n - 1);
    for (int i = 0; i < n; i++) {
        printf("%d ", P[i]);
    }
    return 0;
}

四、总结

通过对原错误代码和修正后代码的对比分析,我们可以清晰地看到快速排序算法实现过程中的易错点。在基准值选择与处理上,要避免基准值在交换中被修改;循环逻辑需妥善处理元素等于基准值的情况,防止无限循环;递归调用要准确确定分区边界。理解并规避这些易错点,有助于正确实现快速排序算法,提升编程的准确性和效率。

posted @ 2025-05-09 20:43  .N1nEmAn  阅读(39)  评论(0)    收藏  举报