快速排序(算法导论实现)

版本一:
QUICKSORT(A, p, r)
1 if p < r
2    then q ← PARTITION(A, p, r)   //关键
3         QUICKSORT(A, p, q - 1)
4         QUICKSORT(A, q + 1, r)

数组划分
快速排序算法的关键是PARTITION过程,它对A[p..r]进行就地重排:
PARTITION(A, p, r)
1  x ← A[r]
2  i ← p - 1
3  for j ← p to r - 1
4       do if A[j] ≤ x
5             then i ← i + 1
6                  exchange A[i] <-> A[j]
7  exchange A[i + 1] <-> A[r]
8  return i + 1

 

ok,咱们来举一个具体而完整的例子。
来对以下数组,进行快速排序,
  2   8   7   1   3   5   6   4(主元)


一、

i p/j

  2   8   7   1   3   5   6   4(主元)
j指的2<=4,于是i++,i也指到2,2和2互换,原数组不变。
j后移,直到指向1..
二、
              j(指向1)<=4,于是i++
i指向了8,所以8与1交换。
数组变成了:
       i          j
  2   1   7   8   3   5   6   4
三、j后移,指向了3,3<=4,于是i++
i这是指向了7,于是7与3交换。
数组变成了:
             i         j
  2   1   3   8   7   5   6   4
四、j继续后移,发现没有再比4小的数,所以,执行到了最后一步,
即上述PARTITION(A, p, r)代码部分的 第7行。
因此,i后移一个单位,指向了8
                 i               j
  2   1   3   8   7   5   6   4
A[i + 1] <-> A[r],即8与4交换,所以,数组最终变成了如下形式,
  2   1   3   4   7   5   6   8
ok,快速排序第一趟完成。


4把整个数组分成了俩部分,2 1 3,7 5 6 8,再递归对这俩部分分别快速排序。
i p/j
  2   1   3(主元)
  2与2互换,不变,然后又是1与1互换,还是不变,最后,3与3互换,不变,
最终,3把2 1 3,分成了俩部分,2 1,和3.
再对2 1,递归排序,最终结果成为了1 2 3.

7 5 6 8(主元),7、5、6、都比8小,所以第一趟,还是7 5 6 8,
不过,此刻8把7 5 6 8,分成了  7 5 6,和8.[7 5 6->5 7 6->5 6 7]
再对7 5 6,递归排序,最终结果变成5 6 7 8。

ok,所有过程,全部分析完成。
最后,看下我画的图:



#include<iostream>

using namespace std;
void quick_sort(int a[], int begin,int end); 
int partition(int a[], int p, int r); 
void swap(int &num1,int &num2);


int main(){
    
    int a[]={ 46, 58, 15, 45, 90, 18, 10, 62};
    
    quick_sort(a,0,8);
    
    for ( int i = 0; i < 8; ++i){
         cout<<a[i]<<" ";
     }
    system("pause");
    return 0;





void swap(int &num1,int &num2)
{
     int temp = num1;
     num1 = num2;
     num2 = temp;
     

}

//递归调用,当begin 小于 end时候,才进行

//也就是说结束时候只剩下一个元素了,begin大于等于end

//所以下面花括号错了

void quick_sort(int a[], int begin,int end)
{
     int q;
     if (begin < end){
        q = partition(a,begin,end);

     } 

//还有此时end的值是数组长度,所以这第三个参数应该对应,改成q

     quick_sort(a, begin,q -1);

     quick_sort(a, q+1,end); 


}//insert 


int partition(int a[], int p, int r)
{
  int x,i,j;
  x = a[r-1];
  i = p - 1;
  for(j=p;j<=r-2;j++ ){
                     if(a[j]<=x){ 
                                  i = i+1;
                                  swap(a[i],a[j]);
                     }
                     
  }

 //把数组最后一个元素做为比较的对象,把比他小的放左边,比他大的放右边,等循环到j为r-1的时候结束,

//最后把这个用来比较的元素放在中间

//下面这句话的错误在于是应该把它放中间,所以是  swap(a[i+1],a[r]);

  swap(a[i+1],a[j]);
  
  return i + 1;

}//insert


//正确的程序改成下面的:

#include<iostream>
using namespace std;
void quick_sort(int a[], int begin,int end);
int partition(int a[], int p, int r);
void swap(int &num1,int &num2);

int main(){

    int a[]={ 46, 58, 15, 45, 90, 18, 10, 62};

    quick_sort(a,0,7);

    for ( int i = 0; i < 8; ++i){
         cout<<a[i]<<" ";
     }

    return 0;

}

void swap(int &num1,int &num2)
{
     int temp = num1;
     num1 = num2;
     num2 = temp;

}
void quick_sort(int a[], int begin,int end)
{
     int q;
     if (begin < end){
        q = partition(a,begin,end);

     quick_sort(a, begin,q-1 );
     quick_sort(a, q+1,end);
     }
}//insert 

int partition(int a[], int p, int r)
{
  int x,i,j;
  x = a[r];
  i = p - 1;
  for(j=p;j<=r-1;j++ ){
                     if(a[j]<=x){
                                  i = i+1;
                                  swap(a[i],a[j]);
                     }

  }

  swap(a[i+1],a[j]);

  return i + 1;
}//insert 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值