快速排序其实很简单

1.快速排序概述

快速排序在数组中选择一个基准值,将数组分为 两部分,第一部分的所有元素都小于或等于基准元素,第二部分都大于或等于基准元素,再分别对两部分递归调用排序算法

2.快速排序的基本步骤

1)找基准元素(以数组的第一个元素为例)
2)划分区域(使小的元素都在左边,大的元素都在右边)
3)递归调用排序算法

3.快速排序的划分区域算法

1)一遍单向扫描法

  • 用两个指针sp和bigger将数组划分为3个区间
  • 扫描指针sp是确认小于等于基准元素的,初始指向基准元素的下一个元素
  • bigger指针指向数组最后一个元素(未知区间末指针),确认大于基准的元素
  • 当扫描指针指向的值小于或等于基准值时,扫描指针继续向右移动
  • 当扫描指针指向的值大于基准值的元素,和bigger指针指的元素交换,bigger指针向前移动
    在这里插入图片描述
    如图所示,一趟完成后此时bigger指针指向小于基准值的最后一个元素,sp指针指向大于基准值得第一个元素,所以,此时基准值和bigger指针指向的元素交换位置(基准值归位)
    2)双向扫描法
  • 定义两个指针left和right
  • left指向基准元素后面的那个元素,right指向序列的最后一个元素
  • left指针往中间扫描,从左边找到大于基准值的元素时停下,right指针向前扫描,从右边找小于等于基准值的元素时停下,此时二者交换,然后继续扫描,直到左侧无大元素,右侧无小元素

4.代码实现

1)一遍单向扫描法

/*
 * 快排的划分算法1:
 *     一遍单向扫描法
 *         用两个指针将数组划分为3个区间
 *         扫描指针左边是确认小于等于基准元素的
 *         bigger指针指向数组最后一个元素(未知区间末指针),确认大于基准的元素
 *         当扫描指针指向的值小于基准值,扫描指针继续向右移动
 *         当扫描指针指向的值大于基准值的元素,和bigger指针指的元素交换,bigger指针向前移动
 */    
import java.util.Arrays;
public class QuickSort {
	public static void main(String[] args) {
		int[] array = {2,3,12,8,98,56,33,7,7};
		quickSort(array,0,array.length - 1);
		System.out.println(Arrays.toString(array));	
	}
	public static void quickSort(int[] array, int begin, int end) {
		if(begin < end) {
			int q = partition(array,begin,end);//q为基准元素的位置
			quickSort(array,begin, q - 1); //对左侧元素递归排序
			quickSort(array,q + 1,end);//对右侧元素递归排序
		}
	}
	public static int partition(int[] array, int begin,int end) {
	int value = array[begin]; //基准元素
	int sp = begin + 1;  //左指针(扫描指针)
	int bigger = end; //右指针
	while(sp <= bigger) {
		if(array[sp] <= value) {  //比基准元素小,指针继续向前移动扫描
			sp++;
		}
		else {   //比基准元素大,先和bigger指向的元素交换,bigger指针向前移
			int temp = array[bigger];
			array[bigger] = array[sp];
			array[sp] = temp;
			bigger--;
		}
	}//一趟完成后,此时bigger指针指向最后一个小于基准元素的元素,sp指向第一个大于基准元素的值
	int temp = array[bigger];   //基准元素归位
	array[bigger] = array[begin];
	array[begin] = temp;
	return bigger;
	}
}
2)双向扫描法

```java
/*
 * 快排的划分算法2:
 *   双向扫描法:
 *       思路:头尾指针往中间扫描,从左边找到大于基准值得元素,从右边找小于等于基准值的元素,二者交换,继续扫描,直到左侧无大元素,右侧无小元素
 */
import java.util.Arrays;
public class QuickSort2 {
	public static void main(String[] args) {
		int[] array = {2,3,12,8,98,56,33,7,7};
		quickSort(array,0,array.length - 1);
		System.out.println(Arrays.toString(array));	
		
	}
	public static void quickSort(int[] array, int begin, int end) {
		if(begin < end) {
			int q = partition(array,begin,end);
			quickSort(array,begin, q - 1);
			quickSort(array,q + 1,end);
		}
	}
	public static int partition(int[] array, int begin,int end) {
		int value = array[begin]; //基准元素
		int left = begin + 1;  //左指针(扫描指针)
		int right = end; //右指针
		while(left <= right) {
			while(left <= right && array[left] <= value) {
				left++;
			}
			while(left <= right && array[right] > value) {
				right--;
			}
			if(left < right) {
				int temp = array[left];   //左右指针所指向的值交换位置
				array[right] = array[left];
				array[left] = temp;
			}
		}
		//循环退出时,两个指针位置交错,且right指向最后一个小于等于基准值的元素,left指向第一个大于基准值的元素。此时交换基准值和right所指向的元素
		int temp = array[right];
		array[right] = array[begin];
		array[begin] = temp;
		return right;
		}

}


发布了33 篇原创文章 · 获赞 3 · 访问量 3807

猜你喜欢

转载自blog.csdn.net/qq_43169220/article/details/103002838