快速排序法

来源:互联网 发布:交通规划与仿真软件 编辑:程序博客网 时间:2024/06/06 01:41
/*--------------------------------------------------------------------------------------------
                                             快速排序法
排序原理:找出一个中间元素,让左边的值均小于它,右边的值均大于它.然
                 后再分别对左边和右边进行同样处理的方式排序.第一次用到的
                 中间元素可以取中间元素也可以取第一个元素,这里取第一个元
                 素,所以先找右边第一个小于它的值,将该值赋给第一个元素,还
                 是用一个短小的例子说明吧!(最基本的原理应该是用的分治法.)
                 下面拿10个元素为例进行说明:
                 ---------------------------------------------------------
                 23   45   34   5   765   74   657   88   99   87
                 ---------------------------------------------------------
                 第一次:  left=0;
                                right=9;
                 调用Find_Mind(ar,left,right)分析如下:
                 temp=ar[left]=ar[0]=23;
                1.在left右边寻找第一个小于23的元素(5),并把它赋给
                    ar[left],此时排序结果:
                  --------------------------------------------------------
                  5   45   34   5   765   74   657   88   99   87
                  ---------------------------------------------------------
                 此时:left=0+1=1;(赋值语句结束后需要将left右移一位)
                          right=3;
                 2.在right左边从left(1)开始寻找第一个大于5的元
                     素(45),然后将其赋给ar[right],此时排序结果:
                 ---------------------------------------------------------
                 5   45   34   45   765   74   657   88   99   87
                 ---------------------------------------------------------
               此时:left=1;
                        right=1;(赋值语句结束后需要将right左移一位)


第二次:是在Quick_Sort(ar,left,mid-1);这步的递归调用规程中,但是需
             要注意,这里的left是主函数在调用Quick_Sort(ar,0,n-1)是传递
             来的实参0,注意区这里的left和Find_Mid()中的left,实在不行可
             用其他字母代替Find_Mid()中的left和right便可.但是这时传递的
             left和min-1都是0,所以被if(left<right)语句挡住不能进入{}内
             部求mid了,这时便要将控制权返回给调用Quick_Sort(ar,left,mid-1);
             函数的下一个可执行语句,就是Quick_Sort(ar,mid+1,right);将上
            次求的的mid和主函数参来的right带入为Quick_Sort(ar,2,9);这时
            满足if(left<right),所以会调用Find_Mid()函数,继续求中间值.
            步骤同第一次相同,具体参数如下:
            mid=1;
            right=9;
            调用Quick_Sort(ar,mid+1,right);


中间的n次.................................


            直到调用的Quick_Sort()中的两个参数相差为1时,便得出结果.


            对以上的数组,输出结果应为:
            1 : left = 1  right = 1
            2 : left = 2  right = 2
            3 : left = 3  right = 3
            4 : left = 9  right = 9
            5 : left = 5  right = 5
            6 : left = 8  right = 8
            7 : left = 7  right = 7
           ar[10] = 5  23  34  45  74  87  88  99  657  765
--------------------------------------------------------------------------------------------*/
#include<stdio.h>int Find_Mid(int ar[],int left,int right);void Quick_Sort(int ar[],int lrft,int right);int main(void){int i,n;puts("Input the number of elements to the array:");scanf("%d",&n);int ar[n];                      //变长数组,编译器应支持C99标准printf("Input %d elements of the array:\n",n);for(i=0;i<n;i++)                //读取数组元素scanf("%d",&ar[i]);Quick_Sort(ar,0,n-1);               printf("ar[%d] = ",n);for(i=0;i<n;i++)                //逐个打印数组元素             printf("%d  ",ar[i]);   putchar('\n');return 0;}void Quick_Sort(int ar[],int left,int right){int mid;if(left<right){mid=Find_Mid(ar,left,right);     //求中间位置Quick_Sort(ar,left,mid-1);       //递归调用,对左边进行相同方式的分发Quick_Sort(ar,mid+1,right);      //递归调用,对右边进行相同方式的分发}}int Find_Mid(int ar[],int left,int right){static int ct;                                //声明一个静态变量用于计算调用Find_Mid()的次数int temp;if(left<right){temp=ar[left];while(left<right){while(left<right && ar[right]>=temp)   //右侧寻找第一个小于temp的元素right--;if(left<right)                         //left<right说明找到了,所以将找到的元素赋值给s[left]ar[left++]=ar[right];while(left<right && ar[left]<temp)     //左侧寻找第一个大于等于temp的元素left++;if(left<right)                         //left>right说明找到了,所以将找到的元素赋值给s[left]ar[right--]=ar[left];}ct++;}printf("%d : left = %d   right = %d\n",ct,left,right);//输出每次调用后的left和right,应该相等ar[left]=temp;                                        //将比较的元素赋给找到的位置return left;}

原创粉丝点击