您的位置:首页 > 其它

qsort快速排序总结

2016-07-06 16:15 211 查看

假设用户输入了如下数组:

下标

0

1

2

3

4

5

数据

6

2

7

3

8

9

创建变量i=0(指向第一个数据), j=5(指向最后一个数据), k=6(赋值为第一个数据的值)。

我们要把所有比k小的数移动到k的左面,所以我们可以开始寻找比6小的数,从j开始,从右往左找,不断递减变量j的值,我们找到第一个下标3的数据比6小,于是把数据3移到下标0的位置,把下标0的数据6移到下标3,完成第一次比较:

下标

0

1

2

3

4

5

数据

3

2

7

6

8

9

i=0 j=3 k=6



接着,开始第二次比较,这次要变成找比k大的了,而且要从前往后找了。递加变量i,发现下标2的数据是第一个比k大的,于是用下标2的数据7和j指向的下标3的数据的6做交换,数据状态变成下表:

下标

0

1

2

3

4

5

数据

3

2

6

7

8

9

i=2 j=3 k=6

称上面两次比较为一个循环。

接着,再递减变量j,不断重复进行上面的循环比较。



在本例中,我们进行一次循环,就发现i和j“碰头”了:他们都指向了下标2。于是,第一遍比较结束。得到结果如下,凡是k(=6)左边的数都比它小,凡是k右边的数都比它大:

下标

0

1

2

3

4

5

数据

3

2

6

7

8

9

如果i和j没有碰头的话,就递加i找大的,还没有,就再递减j找小的,如此反复,不断循环。注意判断和寻找是同时进行的。

然后,对k两边的数据,再分组分别进行上述的过程,直到不能再分组为止。

注意:第一遍快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。


使用示例:












void sort(int *a, int left, int right)

{

    if(left >= right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/

    {

        return ;

    }

    int i = left;

    int j = right;

    int key = a[left];

     

    while(i < j)                               /*控制在当组内寻找一遍*/

    {

        while(i < j && key <= a[j])

        /*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升

        序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/ 

        {

            j--;/*向前寻找*/

        }

         

        a[i] = a[j];

        /*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是

        a[left],那么就是给key)*/

         

        while(i < j && key >= a[i])

        /*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,

        因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/

        {

            i++;

        }

         

        a[j] = a[i];

    }

     

    a[i] = key;               /*当在当组内找完一遍以后就把中间数key回归*/

    sort(a, left, i - 1);    /*最后用同样的方式对分出来的左边的小组进行同上的做法*/

    sort(a, i + 1, right); /*用同样的方式对分出来的右边的小组进行同上的做法*/

                                       /*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: