快速排序 Quicksort

分治法的基本思想(Divide-and-Conquer):

将原问题分解为若干个规模更小,但结构与原问题相同的子问题。递归的解决这些子问题,然后将这些子问题的解组合成原问题的解。

快速排序基本思想:

快速排序是一种划分交换排序,它的基本思想是,通过一趟排序将记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,然后用递归的方法再分别对分割所得的两个子序列进行快速排序。

设当前待排序的序列为R[low...high],利用分治法可以将快速排序的基本思想描述为:

1. 分解:

在R[low...high]中任选一个记录(通常选第一个记录)作为基准(pivot),以此基准将当前无序序列划分为左,右两个较小的子区间R[low...pivotpos-1]和[pivotpos+1...high],左边子区间中所有记录的关键字均小于或等于基准记录的关键字pivot.key, 右边子区间中所有记录的关键字均大于或等于基准记录的关键字pivot.key, 而基准记录pivot则位于正确的位置上pivotpos,无须参加后续的排序。划分的关键是要求出基准记录的位置pivotpos.

2. 求解:

通过递归调用快速排序,对左,右子区间进行快速排序。

3. 组合:

因为当“求解”步骤中的两个递归调用结束时,其左,右两个子区间已经有序。所以对快速排序而言,"组合"步骤什么也不用做。

划分算法 Partition:

1. 初始化:设置两个指针i和j,他们的初始值分别为区间的下界和上界,即i=low, j=high。选取无序区间的第一个记录R[i](即R[low])作为基准记录,并将它保存在变量pivot中。

2. 令j自high起向左扫描,直到找到第1个关键字小于pivot的记录R[j], 将R[j]和基准R[i]进行交换,交换后,R[j]中存放了pivot

3. 然后令i指针自i+1的位置开始向右扫描,直到找到第一个关键字大于pivot的记录R[i],将R[i]和基准R[j]进行交换,交换后R[i]中又存放了pivot

4. 接着令指针j自位置j-1开始向左扫描,如此交替改变扫描方向,直至i=j时,i便是基准pivot最终的位置,就完成了一次划分

 

快速排序的时间复杂度:

快速排序是一种不稳定的排序方法。其平均时间复杂度为O(nlgn), 最差情况下时间复杂度为O(n2)。

 

JAVA实现的快速排序:

//对source快速排序
public class QuickSort {
    public static void quickSort(int source[], int low, int high) {
     int pivotpos;                                                                  //划分后的基准记录的位置
     if(low<high) {                                                                //仅当区间长度大于1时才排序
      pivotpos = Partition(source, low, high);                           //对source[low...high]做划分
         quickSort(source,low,pivotpos-1);                               //对左区间递归排序
         quickSort(source,pivotpos+1,high);                             //对右区间递归排序
     }     
 
    }
 
//调用Partition(source,low,high)时,对source(low,high)做划分,并返回基准记录的位置

 public static int Partition(int[] source, int low, int high) {
  int pivot = source[low];                                                     //用区间的第一个记录作为基准
  while(low < high) {                                                           //从区间两端交替向中间扫描,直至 i=j 为止          
   while(low<high && source[high]>pivot) {                         //pivot的位置在i上
    high--;
   }
   swap(source,low,high);                                                     //找到了关键字小于pivot的source[j],交换source[i]和source[j]
   while(low<high && source[low]<pivot) {                          //pivot的位置在j上
    low++;
   }
   swap(source,low,high);                                                     //找到了关键字大于pivot的source[i],交换source[i]和source[j]
  }
  return low;
 }
 
 public static void swap(int source[], int i, int j) {
  int temp;
  temp = source[i];
  source[i] = source [j];
  source[j] = temp;
 }

//测试上面的quickSort方法
 public static void main(String[] args) {
  
        int test[] = {49,38,65,97,76,13,27};
        quickSort(test,0,6);
        for(int i=0; i<test.length;i++) {
         System.out.println(test[i]);
        }
 }

}

输出结果:

13
27
38
49
65
76
97

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值