基本思想

快速排序也是基于分治算法的。步骤如下:

(1)选择一个基准元素,通常选择第一个元素或者最后一个元素;

(2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基 准元素值小。另一部分记录的元素值比基准值大;

(3)此时基准元素在其排好序后的正确位置;

(4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序
如下图所示:
【排序算法(六)】快速排序

Java版本实现

package sort;

public class QuickSort<T extends Comparable<? super T> > {
	
	private T a[];
	
	public QuickSort(T a[]) {
		this.a = a;
	}

	public void quickSort() {
		quickSort(0 , a.length - 1);
	}
	
	private void quickSort(int low , int high) {

		if(low >= high) {
			return;
		}else {
			T pivot = a[low];
			int partition = partition(low , high ,pivot);
			
			quickSort(low , partition - 1);
			quickSort(partition + 1 , high);
			
		}
	}

	private int partition(int low, int high , T pivot) {
		while(low < high) {
			
			while(low < high && pivot.compareTo(a[high]) <= 0) {
				high --; 
			}
			swap(low , high);
		
			while(low < high && pivot.compareTo(a[low]) >= 0) {
				low ++;
			}
			swap(low , high);
			System.out.print("            ");
			display();
		}
		return low;
	}

	private void swap(int low, int high) {
		
		T temp = a[low];
		a[low] = a[high];
		a[high] = temp;
		
	}
	
	public void display() {
		for(int i = 0 ; i < a.length; i ++ ) 
			System.out.print(a[i] + "   ");
		System.out.println();
	}
	
	public static void main(String[] args) {
		Integer a[] = {57,68,59,52,72,28,96,33,24,19};
		QuickSort<Integer> qs = new QuickSort<>(a); 
		System.out.print("before sort:");
		qs.display();
		qs.quickSort();
		System.out.print("after  sort:");
		qs.display();
	}
}

算法分析

在归并排序中,我们详细推算了时间复杂度,快速排序与归并排序一样采取了分治算法,它的时间复杂度也是O(N*log2N)。

对于分治算法一般都是如此,用递归的方法把数据项分为两组,然后调用自身来分别处理每一组数据。算法实际上是以2为底,运行时间与N*log2N成正比。

对于快速排序来说,最理想的状态是随机分布的数据,即我们任意选定的枢纽处于中间位置,有一半元素小于它,有一半元素大于它。当数据时由小到大排列或者由大到小排列时,快速排序的效率最低,时间复杂度扩大为O(N2)。

算法改进

选定第一个元素为枢纽实现起来确实很简单,但是当它为最大值或最小值时,快速排序的效率会严重降低。假如选中的元素为数组的中值,自然是最好的选择,但是却要遍历整个数组来确定中值,这个过程可能比排序花费的时间还长,得不偿失。折衷的方法是找到数组中的第一个、最后一个以及处于中间位置的元素,选出三者的中值作为枢纽,既避免了枢纽是最值的情况,也不会像在全部元素中寻找中值那样费时间。这种方法被称为“三项取中法”(median-of-three)。

Java版本实现

public void quickSort2() {
		quickSort2(0 , a.length - 1);
	}
	
	private void quickSort2(int low , int high) {

		if(low >= high) {
			return;
		}else {
			
			T pivot = pivot(low ,high);
			int partition = partition(low , high , pivot);
			
			quickSort2(low , partition - 1);
			quickSort2(partition + 1 , high);
			
		}
	}
	
	private T pivot(int left , int right) {
		
		int mid = ( left + right ) / 2;
		if(a[mid].compareTo(a[right]) > 0)
			swap(mid , right);
		if(a[left].compareTo(a[right]) > 0)
			swap(left , right);
		if(a[mid].compareTo(a[left]) > 0)
			swap(mid, left);
		
		return a[left];
	}

	private void swap(int low, int high) {
		
		T temp = a[low];
		a[low] = a[high];
		a[high] = temp;
	}

相关文章:

  • 2021-11-08
  • 2021-10-17
  • 2021-08-10
  • 2021-07-19
猜你喜欢
  • 2021-07-17
  • 2021-08-28
  • 2021-10-11
  • 2021-12-28
  • 2021-10-23
  • 2021-06-27
相关资源
相似解决方案