快速排序(一) 思想 JAVA实现

已知数组59、71、37、56、88、96、21、58、48、43 采用快速排序将数组有序。

快速排序同样采用了“分治策略”,使用递归的思路来实现算法。

快速排序的算法思想:

9、71、37、56、88、96、21、58、48、43   数组元素

0、1、   2、  3、  4、  5、  6、  7、  8、 9     数组下标

选取数组中某一个元素,使得元素左侧的数组元素都小于等于该元素数组右侧的元素都大于该元素.

例如选择元素 58 ,将数组按以上规则进行第一轮排序得

9、37、56、21、48、43、58、88、96。

第一轮排序后满足上述规则。

第二轮将58左右两侧数组再次按上述规则进行排序。(采用递归的思想,直到数组不可分)

。。。。

根据以上思想得知:如何计算某一个元素非常重要,实际上计算这个元素的位置才是本质。这也是快速排序的核心。

快速排序的实现采用了“原址排序”。即在原数组中进行排序,与归并排序需要额外的空间相不同。

实现的思路为:将原数组分为3部分,小于等于某元素,某元素,大于某元素。

实现过程中 选取3个变量来表示数组对应的下标,从而实现三部划分。接下来采用java实现,在代码注释中在详解具体实现思路。

public class QuickOrder {


          private int[] Array;

          private int currentIndex;

          private int maxIndex;

          public QuickOrder(int size) {
                  this.Array = new int[size];
                  this.currentIndex = 0;
                  this.maxIndex = size-1;
          }

          public void insert(int value) {
                  if(this.maxIndex<this.currentIndex) {
                         System.out.println("数组已满");
                  }else {
                        this.Array[this.currentIndex++] = value;
                  }
          }
          //开始进行排序
          public void quickOrder() {
                   this.order(0, this.currentIndex-1);//传入数组起始下标,与最后一个元素下标
           }

          private void order(int start,int end) {
                  if(start<end) {//递归条件,起始下标小于最后一个元素下标,即数组有不止一个元素
                      int position = this.position(start, end); //计算某一元素的位置
                      this.order(start, position-1);//将左侧继续递归进行排序。
                      this.order(position+1, end);//将右侧继续递归进行排序。
                  }
          }

          private int position(int start,int end) {
                  int minIndex = start-1;//作为小于等于部分的数组下标。
                  int moveIndex = start;//作为一个指针移动,且 minIndex与moveIndex之间的元素为大于部分
                  int aim = this.Array[end];//这里选择数组最右侧元素作为某一元素,这是快速排序其中一种简单实现,在后续文章中,将会有对某一元素选取的优化。
                  while(moveIndex<=end-1) {
                          if(this.Array[moveIndex]<=aim) {//如果元素小于目标值,将此元素放入0到minIndex部分中,同时minIdex加1(在满足条件之前,0到moveIndex之前的元素均已满足大于aim,所以当满足条件时,只需将不满足元素与之前满足的元素进行交换即可)。
                               minIndex = minIndex+1;
                               this.exchange(moveIndex, minIndex);
                           }
                          moveIndex++;//同时指针向后移动
                 }
                 this.exchange(minIndex+1, end);//最后将目标值,移动到小于等于部分与大于部分之间
                 return minIndex+1;//返回目标值的数组小标
         }
         //执行交换
          private void exchange(int x,int y) {
                  int temp = this.Array[x];
                  this.Array[x] = this.Array[y];
                  this.Array[y] = temp;
          }

          public void show() {
                  for (int i : Array) {
                       System.out.println(i);
                  }
           }
}

 快速排序的平均运行时间为O(NlgN),最坏运行情况为O(N²)。与数组情况以及某一元素的选取有关。将在以后文章中讲述其优化。

最终排序结果为: 21、37、43、48、56、58、59、71、88、96

往前走,别回头!
原文地址:https://www.cnblogs.com/dev1ce/p/10618478.html