zoukankan      html  css  js  c++  java
  • 排序算法--快速排序

            快速排序是效率较高的排序方法,采用了分治法。将一个大的数组分解成多个小数组,保证每一个小数组是顺序的,则整个大数组也就是顺序的了。

            我学习的过程是这样的:

                   1 先看了下维基百科上面的解释。

                   2 自己分析整个过程。

                   3 写代码实现。


            维基百科的解释如下:

    1. 从数列中挑出一个元素,称为 "基准"(pivot),
    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

            有了如上的解释,我们自己分析下这个过程。

            首先是有一个数组。然后我们随便选取一个数字作为基准,将所有小于该数字的元素,移动到左侧。所有大于该数字的元素,移动到该数字的右侧。我们这里有个方法,就是基准元素,总是选择这个数组序列的第一个元素。这样的话,我们只用将小于该数字的元素移动到左侧来即可。然后以这个基准元素的下标为基准点,将该数组分成两段,然后针对这两个数组,确定其基准,再次排序。一直到所有的元素都确定顺序后,整个排序过程结束。

            看看整段代码的结构。

    package com.bplead.sort;
    
    public class QuickSort {
    	
    	public static void qsort(int a[],int begin,int end){
    		if(begin > end){
    			return;
    		}	
    		prt(a);
    		int pivotindex = partition(a,begin,end);
    		qsort(a,begin,pivotindex-1);
    		qsort(a,pivotindex+1,end);
    	}
    	
    	public static int partition(int a[],int left,int right){
    		int keyindex = left;
    		int temp = 0;
    		for(int i=left+1;i<=right;i++){
    			if(a[i] < a[keyindex]){
    				temp = a[i];
    				for(int j=i;j>keyindex;j--){
    					a[j] = a[j-1];
    				}
    				a[keyindex] = temp;
    				keyindex ++;
    			}
    		}
    		return keyindex;
    
    	}
    	
    	public static void main(String[] args) {
    		int array[] = {43,24,12,56,78,9,67,50,1,2,1,9,87};
    		qsort(array,0,array.length-1);
    		
    	}
    	
    	private static void prt(int[] array){
    		for(int i=0;i<array.length;i++)
    			System.out.print(array[i] + " ");
    		System.out.println();
    	}
    	
    }
    


            其实,整个快速排序的难点就在于基准元素位置的确定了。一旦确定了基准元素的位置,然后以此位置为分割点,将数组分为2个,递归进行处理即可。

            我们看一下partition分区函数把。

            我们将基准元素选择为第一个元素,循环遍历整个数组,使其元素和基准元素进行比较,如果遍历的当前元素比基准元素小,则当前元素以前的所有元素(不包含当前元素)都向右移动一位,当前元素放置到基准元素以前。一个分区函数执行完成后,所有小于该基准元素的元素都会移动到基准元素左侧了。

            我这里把整个快速排序的过程都打印出来了,过程如下:

    43 24 12 56 78 9 67 50 1 2 1 9 87 
    24 12 9 1 2 1 9 43 56 78 67 50 87 
    12 9 1 2 1 9 24 43 56 78 67 50 87 
    9 1 2 1 9 12 24 43 56 78 67 50 87 
    1 2 1 9 9 12 24 43 56 78 67 50 87 
    1 2 1 9 9 12 24 43 56 78 67 50 87 
    1 1 2 9 9 12 24 43 56 78 67 50 87 
    1 1 2 9 9 12 24 43 56 78 67 50 87 
    1 1 2 9 9 12 24 43 56 78 67 50 87 
    1 1 2 9 9 12 24 43 50 56 78 67 87 
    1 1 2 9 9 12 24 43 50 56 78 67 87 
    1 1 2 9 9 12 24 43 50 56 67 78 87 
    1 1 2 9 9 12 24 43 50 56 67 78 87 

    原数组是:

                     43  24  12  56  78  9  67  50  1  2  1  9  87 

    第一次分区操作:我们选择43为基准,则所有小于43的元素均在43左侧。得到如下序列。

                    24  12  9  1  2  1  9  43  56  78  67  50  87

    第二次分区操作,将43以前的元素当作一个序列,以后的元素也当作一个序列。我们需要注意的是,已经确定过的这个基准元素,作为分割数组的标记,该元素不用划分到左右两个数组中。




            



  • 相关阅读:
    Vector用法。
    error LNK2001的解决方法
    指针(详解)
    xxx cannot be resolved to a type
    springmvc写了方法无法访问
    java lombok包在maven已经配置,但是注解没用
    系统提供的相关intent
    Activity小结
    BrocastReceiver入门
    AppWidget入门
  • 原文地址:https://www.cnblogs.com/james1207/p/3262720.html
Copyright © 2011-2022 走看看