快速排序的JAVA实现

快速排序:

快速排序也属于交换排序,它是对冒泡排序的改进。它的基本思想:

(1)从当前序列中选择一个元素作为分界元素,称为支点。定义两个指针i,j,让j指针从后往前找,找到第一个比支点小的元素和支点交换。让i指针从前往后找,找到第一个比支点大的元素与支点交换。这样,最终找到支点的位置k.

(2)以支点的位置为中心,把序列分为左右两个部分,分别对左右两个部分进行上述过程。直到子序列的长度为1,从而整个序列有序。

 

快速排序算法的JAVA实现:

第一种:双向交换,选择最左边的端点为轴,从j向前找时,把轴元素与比它小的元素交换,然后从i向后找时,把轴元素与比它大的元素交换。

第二种:单向交换,选择最左边的端点为轴,从j向前找时,把比它小的元素r[i]=r[j].然后i从前向后找。把比轴大的元素r[j]=r[i].

第三种:中心交换。选择中间的端点为轴,从j向前找到比轴的小的元素,从i向后找到比轴大的元素,然后把它们交换。这样,轴左边的元素始终比轴小,轴右边的元素始终比轴大。

 

下面是这三种算法的JAVA实现:

 

public class QuickSort {

 /**
  *
  * 快速排序算法:先找到一个基准,然后分别从左右进行寻找,从左边找到第一个比这个轴大的元素
  * 从右边找到第一个比这个轴小的元素进行交换,直到右边的指针大于左边的指针为止.然后在左右两边 在选择轴进行递归的进行上述操作.
  *
  * @param args
  */

 public static void main(String[] args) {

  int[] s = { 13, 15, 7, 10, 20, 4, 8, 19 };
  // s = quicksort(s, 0, s.length - 1);
  s = quicks(s, 0, s.length - 1);
  for (int i : s) {

   System.out.print(i + " ");
  }

 }

 public static int[] quickd(int[] num, int left, int right) {
  if (left < right) {
   int k = doublequick(num, left, right);
   System.out.println("k=" + k);
   quickd(num, left, k - 1);
   quickd(num, k + 1, right);
  }
  return num;
 }

 public static int[] quicks(int[] num, int left, int right) {
  if (left < right) {
   int k = singlequick(num, left, right);
   System.out.println("k=" + k);
   quicks(num, left, k - 1);
   quicks(num, k + 1, right);
  }
  return num;
 }

 //双向交换

 public static int doublequick(int[] s, int left, int right) {
  int i = left;
  int j = right;
  int temp;
  int x = s[i];// 左边第一个元素为轴,进行交换,从而得到x的正确位置
  while (i < j) {
   while (i < j && s[j] >= x)
    j--;// 首先从右向左找,找到第一个比x小的,然后和x交换
   temp = s[j];
   s[j] = s[i];
   s[i] = temp;
   while (i < j && s[i] <= x)
    i++;// 然后从左向右找,找到第一个比x大的,然后和x交换
   temp = s[j];
   s[j] = s[i];
   s[i] = temp;
  }

  return i;

 }
   //单向交换
 public static int singlequick(int[] s, int left, int right) {
  int i = left;
  int j = right;
  int x = s[left];
  while (i < j) {
   while (i < j && s[j] >= x)
    j--;
   s[i] = s[j];
   while (i < j && s[i] <= x)
    i++;
   s[j] = s[i];
  }
  s[i] = x;
  System.out.println("i=" + i);
  return i;
 }
   //中间为轴,左右交换
 public static int[] quicksort(int[] s, int left, int right) {
  // 关键字的先取
  int i = left;
  int j = right;
  int middle = s[(i + j) / 2];
  System.out.println(middle);
  do {
   while (i <= right && middle > s[i])
    i++;// 找到第一个大小等于middle的元素
   while (j >= left && middle < s[j])
    j--;// 找到第一个小于middle元素

   if (i <= j) {// 表示找到此元素
    // 进行交换
    int temp = s[j];
    s[j] = s[i];
    s[i] = temp;
    i++;
    j--;

   }

  } while (i <= j);

  for (int k : s) {

   System.out.print(k + " ");
  }

  if (left < j) {

   // 左部分递归调用
   System.out.println("j=" + j);
   quicksort(s, left, j);

  }
  if (right > i) {
   // 右部分递归调用
   System.out.println("i=" + i);
   quicksort(s, i, right);

  }

  return s;

 }

}

 

 

 

性能分析:

时间复杂度:

快速排序的采用递归,其深度为logn,由于每一次划分元素交换n次,所以时间复杂度为nlogn.

空间复杂度:

递归的深度为logn,每一次递归需要一个单元的辅助空间用于交换,因此,空间复杂度为logn.

稳定性:

由于划分轴过程中存在着交换,所以快速排序不稳定。

 

快速排序的空间复杂度与归并排序空间复杂度的区别:

我们知道,快速排序与归并排序都采用递归,然而快速排序是从上向下进行递归的,即从上向下交换。所以所需要的最大辅助空间为logn.

而归并排序是从上向上递归,即从下向上合并的,最先是两个元素合并,逐渐合并到n个元素的有序序列。因此,归并排序的所需要的最大辅助空间为O(n). 这与快速排序是有区别的。

 

至于快速排序的实例,可参考http://www.cnitblog.com/liaoqingshan/archive/2008/03/19/41163.html

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值