1 思路1:双指针思路
给定数组arr[L…R], 假定选择的PIVOT位于最左边L处。
***思路说明:***
可以设置两个指针i和j, i指向数组的最左端L处, j指向数组的最右端R处, 设置i指针的目的是为了从左往右能找到比pivot要大的元素,设置j指针的目的是为了从右往左走能找到比pivot要小的元素。这种方式的思路在于通过交替沿着从右往左、从左往右交换的思路来将pivot交换至最终的位置。
具体来分析,首先j指正从右往左搜索,直到遇到一个比pivot小或者等于的值,将这个值与pivot进行交换,那么此时交换后pivot右边的值都要比pivot的值要大,然后搜索应该切换方向到从左向右搜索(不然如果继续从右往左搜索再找到一个比pivot小或等于的值再与pivot进行交换的话,此时pivot右边就会存在比pivot小的值了,破坏了已经建立好的顺序),找到一个比pivot大的值,再将这个值与pivot进行交换。那么经过两次两次交换,此时pivot左边都是小于等于pivot的值,而pivot第一次交换后的位置及其后面的所有元素都比pivot要大。宏观来看,经过一轮两个方向的替换,数组的左右部分均已经确定位置了,需要待排序的空间只存留在中间一部分了
2 思路2: 单向指针
思路说明: 采取的思路是pivot的位置保持在首位不动,后面的元素通过交换来达到比pivot值小或者等于的排列在前面、比pivot大的值排列在后面的这一效果。
后面交换的做法其实非常巧妙,在解释这个做法之前先阐述另外一种做法:【我们在逻辑上增加一个等长的数组辅助空间(长度=原数组长度-1),从pivot的后面一个位置开始遍历数组,比pivot小的元素依次从前往后放置,比pivot大的元素依次从后往前放置,并记录分界点;最后将这个辅助数组的值按序赋值给原数组,交换分界点与首位pivot的值,即可完成一次左右划分。】而由于划分过程中只涉及到交换,所以可以将原空间直接当做逻辑上的辅助空间,使用两个指针m和n, m用于依次指向后续数组元素,n用于指向辅助空间的逻辑位置,m每指向一个数组元素,就判断该元素是否比pivot小于或者等于,如果是则将该元素与是n指针所指位置的元素进行交换,然后m和n指针各自向后移动。这样到最后,m指针刚好指向数组的边界外的第一个位置,而n指针则指向最后一个比pivot小于或者等于的元素位置处。
3 思路3:其他改进的思路
可以将pivot的位置设置为数组的最后一个元素