18、快速排序(代码)

先分享个视频教学网址,讲的很nice! https://www.bilibili.com/video/BV1it41167v2?from=search&seid=7944545082422790984

  • 概念
快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
  • 思路:
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

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

import java.util.Arrays;

public class QuickSort {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		QuickSort quickSort = new QuickSort();
		int[] arr = {9,6,0,2,5,2,7,1,8};
		quickSort.quickSort(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(arr));

	}
	
	/**
	 * 我们将数组的第一个元素当做基准 pivot
	 * @param arr   待排数组
	 * @param left  左边的索引值(最小的索引值)
	 * @param right 右边的索引值(最大的索引值)
	 */
	public void quickSort(int[] arr, int left, int right) {
		if(left > right) {
			return;
		}
		//定义基准值:规定将数组第一个元素当做基准pivot
		//此时,应该先进行右遍历,再进行左遍历,否则两个索引值相遇时,指向的元素比基准大。
		int pivot = arr[left];
		//首先定义一个变量,用来当左索引
		int i = left;
		//定义一个变量用来当右索引
		int j = right;
		//定义个临时变量,用于元素交换
		int temp;
		
		
		//开始进行右左索引
		while(i != j) {
			
			//先进行右索引,直到找到比pivot小的元素
			while(i < j && arr[j] >= pivot) {
				j--;
			}
			//然后进行左索引,直到找到比pivot大的元素
			while(i < j && arr[i] <= pivot) {
				i++;
			}
			
			//此时,两者应该同时找到符合要求的元素了,将i和j指向的元素进行交换
			temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;			
		}
		
		//此时,i和j指向同一个元素,将这个元素和基准元素进行交换
		arr[left] = arr[i];
		arr[i] = pivot;
		
		//此时,一遍快排完成,
		//同时,对由基准划分的左右两个数组分别进行快排
		quickSort(arr, left, i-1);
		quickSort(arr, i+1, right);	
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章