排序算法学习之快速排序算法

排序算法学习之快速排序算法

1. 快速排序算法的原理

快速排序算法的原理是选取一个值作为标志,将一个数组分为2部分,左边部分的数全部都比标志值小,右边部分都比标志值大,然后分别对左边数组和又边数组进行递归,直到排序完成。
下面是进行一次数组处理的过程:
对以下的数组进行排序:
                      [key]
                        i                                    j
                        33  17  54  15  23  21  37  20  32  24
将数组的第一个数设置为标志


               [key]
[第一次处理]:比较str[i]与str[j]( 如果str[i]<str[j],就执行'j--',然后重复[第一次处理]),发现33>24,即str[i]>str[j],所以将str[i],str[j]互换位置,i 向前进一位,得到如下的数组


                        i-->i                                j
                        24  17  54  15  23  21  37  20  32  33  

                            i                                j
                        24  17  54  15  23  21  37  20  32  33 

                        [key]
[第二次处理]:比较str[i]与str[j]17>33,即str[i]<str[j],所以执行'i++'操作,i右移一位。


                            i-->i                            j
                        24  17  54  15  23  21  37  20  32  33  

                                i                            j
                        24  17  54  15  23  21  37  20  32  33 

                        [key]
[第三次处理]:比较str[i]与str[j]54>33,即str[i]>str[j],所以将str[i],str[j]互换位置,然后执行'j--'操作

                                i                            j
                        24  17  54  15  23  21  37  20  32  33  

                                i                        j<--j
                        24  17  33  15  23  21  37  20  32  54  

                                i                        j
                        24  17  33  15  23  21  37  20  32  54

                [key]       
[第四次处理]:比较str[i]与str[j]33>32,即str[i]>str[j],所以将str[i],str[j]互换位置,然后执行'i++'操作

                                i                        j
                        24  17  33  15  23  21  37  20  32  54

                                i-->i                    j
                        24  17  32  15  23  21  37  20  33  54

                                    i                    j
                        24  17  32  15  23  21  37  20  33  54

                        [key]
[第五次处理]:比较str[i]与str[j]15<33,即str[i]<str[j],所以执行'i++'操作,i右移一位。


                                    i                    j
                        24  17  33  15  23  21  37  20  32  54

                                    i-->i                j
                        24  17  32  15  23  21  37  20  33  54

                                        i                j
                        24  17  32  15  23  21  37  20  33  54

[第六次处理]
。。。。。。

                       [key]                
[第八次处理]:比较str[i]与str[j]37>33,即str[i]>str[j],所以将str[i],str[j]互换位置,然后执行'j--'操作

                                                i        j
                        24  17  33  15  23  21  37  20  33  54

                                                i    j<--j
                        24  17  32  15  23  21  33  20  37  54

                                                i    j
                        24  17  32  15  23  21  33  20  37  54

               [key]
[第九次处理]:比较str[i]与str[j]54>33,即str[i]>str[j],所以将str[i],str[j]互换位置,然后执行'i++'操作


                                                i    j
                        24  17  33  15  23  21  33  20  37  54

                                                i--->j
                        24  17  32  15  23  21  20  33  37  54

                                                    ij
                        24  17  32  15  23  21  20  33  37  54

发现i,j已经相等,此次循环处理结束。








通过上面的过程,成功的将所有比33大的数排在了它的后面,把比33小的数排在了33的前面,得到了第一次处理的结果。

然后再通过对左边2边分别进行递归处理,最终得到排序结果。

2.下面是完整的C语言代码:


#include<stdio.h>

//快速排序函数声明 str为数组地址,left,right分别为排序数组的的左边界和右边界
void sqrtNum(long *str,int left,int right);

//传进来的a,b是2个指针,并将指针所指向地址中储存的数据进行交换
void exchange(long* a,long* b){
    long temp;
    temp=*a;
    *a=*b;
    *b=temp;
}
//主函数
int main(){
    long str[10];
    for(int i=0;i<10;i++){
        scanf("%ld",&str[i]);
    }
    sqrtNum(str,0,9);
    for(int i=0;i<10;i++){
        printf(" %ld",str[i]);
    }
    printf("\n");
    return 0;
}

//排序函数的具体内容
void sqrtNum(long *str,int left,int right){

    //long key=str[left];
    int  kn=left;
    int m=left;
    int n=right;
    while(m<n){

        //当从右读的标志n大于从左开始读的标志m时,一直循环,判断右边读的数组中的数是否比标志[key]大,如果大,就一直执行n--直到str[m]的值大于等于str[n]:执行第二个if语句中的内容,然后break;跳出内循环
        while(m<n){

            if(str[m]<str[n]){
                n--;
            }
            if(str[m]>=str[n]){
                exchange(&str[n],&str[m]);
                m++;
                break;
            }

        }

        //当从右读的标志n大于从左开始读的标志m时,一直循环,判断左边读的数组中的数是否比标志[key]大,如果大,就一直执行m++直到str[m]的值大于等于str[n]:执行第二个if语句中的内容,然后break;跳出内循环
        while(m<n){
            if(str[m]<str[n]){
                m++;
            }
            if(str[m]>=str[n]){
                exchange(&str[n],&str[m]);
                n--;
                break;
            }
        }

    }
    kn=m;

    if(left<right){

        sqrtNum(str, left,kn-1);

        sqrtNum(str, kn+1,right);

    }

}

点赞