快速排序中指针移动顺序如何影响排序效率?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1535个文字,预计阅读时间需要7分钟。
javapublic class FastSort { public static void quickSort(int[] nums, int left, int right) { if (left >=right) { return; } int pivotIndex=partition(nums, left, right); quickSort(nums, left, pivotIndex - 1); quickSort(nums, pivotIndex + 1, right); }
private static int partition(int[] nums, int left, int right) { int pivot=nums[right]; int i=left - 1; for (int j=left; j private static void swap(int[] nums, int i, int j) { int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; }} public class FastSort {
public static void quikSort(int[] nums, int left, int right) {
// 只有一个元素或者无元素,不进行快排
if (left >= right) {
return;
}
// 选取数组左边的元素为基准元素
int num = nums[left];
// 定义首尾指针
int start = left;
int end = right;
// 指针未相交
while (start < end) {
// 先移动左边的指针
while (start < end && nums[start] <= num) {
start++;
}
// 再移动右边的指针
while (start < end && nums[end] >= num) {
end--;
}
// 两指针终止但没相交,交换元素
if (start < end) {
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
}
}
// 两指针相交,将基准元素放入指针相交位置
nums[left] = nums[start];
nums[start] = num;
// 分别对基准元素左右的元素进行快排
quikSort(nums, left, start - 1);
quikSort(nums, start + 1, right);
}
public static void main(String[] args) {
int[] nums = {34, 1, 5, -2, 0, 35, 36, 38};
quikSort(nums, 0, nums.length - 1);
for (int num : nums) {
System.out.print(num + ",");
}
}
}
运行结果:-2,5,0,1,35,34,38,36, 首先要明确快排的步骤: 步骤2的详细过程是: 问题就出在上述步骤4,考虑如下情况: 指针相遇时: 步骤4执行完毕: 显而易见,比基准元素34大的元素35被放到了左边。 为什么会出现这种情况呢? 因为先移动的指针一定会等待后移动的指针,那么指针相交的位置一定是先移动的指针(首指针)先停止的位置,这里先移动的指针是首指针,它的停止条件是指针指向的元素>基准元素,那么最终停止的位置(指针相交位置)的元素也是大于基准元素的(特殊情况另论:一个指针始终没动,另一个指针直接移动到头,此时指针终止并不是元素大小导致的),而我们选取的基准元素是数组的第一个元素,也就是在数组的左边,这样最后比基准元素大的元素就被交换到了数组的左边。 所以,当选取最左边的元素为基准元素时,先移动的指针一定要是右边的指针。 同理,当选取最右边的元素为基准元素时,先移动的指针一定要是左边的指针。 public class FastSort {
public static void quikSort(int[] nums, int left, int right) {
// 只有一个元素或者无元素,不进行快排
if (left >= right) {
return;
}
// 选取数组左边的元素为基准元素
int num = nums[left];
// 定义首尾指针
int start = left;
int end = right;
// 指针未相交
while (start < end) {
// 先移动右边的指针
while (start < end && nums[end] >= num) {
end--;
}
// 再移动左边的指针
while (start < end && nums[start] <= num) {
start++;
}
// 两指针终止但没相交,交换元素
if (start < end) {
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
}
}
// 两指针相交,将基准元素放入指针相交位置
nums[left] = nums[start];
nums[start] = num;
// 分别对基准元素左右的元素进行快排
quikSort(nums, left, start - 1);
quikSort(nums, start + 1, right);
}
public static void main(String[] args) {
int[] nums = {34, 1, 5, -2, 0, 35, 36, 38};
quikSort(nums, 0, nums.length - 1);
for (int num : nums) {
System.out.print(num + ",");
}
}
}
总结
快排注意点:
拓展:如何选取合适的基准点以优化快排速度?
本文共计1535个文字,预计阅读时间需要7分钟。
javapublic class FastSort { public static void quickSort(int[] nums, int left, int right) { if (left >=right) { return; } int pivotIndex=partition(nums, left, right); quickSort(nums, left, pivotIndex - 1); quickSort(nums, pivotIndex + 1, right); }
private static int partition(int[] nums, int left, int right) { int pivot=nums[right]; int i=left - 1; for (int j=left; j private static void swap(int[] nums, int i, int j) { int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; }} public class FastSort {
public static void quikSort(int[] nums, int left, int right) {
// 只有一个元素或者无元素,不进行快排
if (left >= right) {
return;
}
// 选取数组左边的元素为基准元素
int num = nums[left];
// 定义首尾指针
int start = left;
int end = right;
// 指针未相交
while (start < end) {
// 先移动左边的指针
while (start < end && nums[start] <= num) {
start++;
}
// 再移动右边的指针
while (start < end && nums[end] >= num) {
end--;
}
// 两指针终止但没相交,交换元素
if (start < end) {
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
}
}
// 两指针相交,将基准元素放入指针相交位置
nums[left] = nums[start];
nums[start] = num;
// 分别对基准元素左右的元素进行快排
quikSort(nums, left, start - 1);
quikSort(nums, start + 1, right);
}
public static void main(String[] args) {
int[] nums = {34, 1, 5, -2, 0, 35, 36, 38};
quikSort(nums, 0, nums.length - 1);
for (int num : nums) {
System.out.print(num + ",");
}
}
}
运行结果:-2,5,0,1,35,34,38,36, 首先要明确快排的步骤: 步骤2的详细过程是: 问题就出在上述步骤4,考虑如下情况: 指针相遇时: 步骤4执行完毕: 显而易见,比基准元素34大的元素35被放到了左边。 为什么会出现这种情况呢? 因为先移动的指针一定会等待后移动的指针,那么指针相交的位置一定是先移动的指针(首指针)先停止的位置,这里先移动的指针是首指针,它的停止条件是指针指向的元素>基准元素,那么最终停止的位置(指针相交位置)的元素也是大于基准元素的(特殊情况另论:一个指针始终没动,另一个指针直接移动到头,此时指针终止并不是元素大小导致的),而我们选取的基准元素是数组的第一个元素,也就是在数组的左边,这样最后比基准元素大的元素就被交换到了数组的左边。 所以,当选取最左边的元素为基准元素时,先移动的指针一定要是右边的指针。 同理,当选取最右边的元素为基准元素时,先移动的指针一定要是左边的指针。 public class FastSort {
public static void quikSort(int[] nums, int left, int right) {
// 只有一个元素或者无元素,不进行快排
if (left >= right) {
return;
}
// 选取数组左边的元素为基准元素
int num = nums[left];
// 定义首尾指针
int start = left;
int end = right;
// 指针未相交
while (start < end) {
// 先移动右边的指针
while (start < end && nums[end] >= num) {
end--;
}
// 再移动左边的指针
while (start < end && nums[start] <= num) {
start++;
}
// 两指针终止但没相交,交换元素
if (start < end) {
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
}
}
// 两指针相交,将基准元素放入指针相交位置
nums[left] = nums[start];
nums[start] = num;
// 分别对基准元素左右的元素进行快排
quikSort(nums, left, start - 1);
quikSort(nums, start + 1, right);
}
public static void main(String[] args) {
int[] nums = {34, 1, 5, -2, 0, 35, 36, 38};
quikSort(nums, 0, nums.length - 1);
for (int num : nums) {
System.out.print(num + ",");
}
}
}
总结
快排注意点:
拓展:如何选取合适的基准点以优化快排速度?

