快速排序

快速排序

快速排序,看名字就毫不谦虚

快速排序是对冒泡排序的一种升级,应该是目前最快的排序算法

具体方法为

选取数组第一个数23为基准数,存入temp变量中,从数组的左右两边界向中间进行遍历,定义两个指针 i 和 j,i 最开始指向数组的第一个元素,j 最开始指向数组的最后一个元素。指针 i 从左向右移动,指针 j 从右向左移动。先移动 j 指针(从右忘左移),当 j 指向的数大于基准数时,略过,j 继续往左移动,直到遇到小于等于基准数的数arr[j],将arr[j]填入arr[i]中;再移动 i 指针,当 i 指向的数小于等于基准数时,略过,i 继续往右移动,直到遇到不比基准数小的数arr[i],将arr[i]填入arr[j]中;再移动 i 指针,再移动 j 指针…(轮换移动),直到 i 和 j 指针相遇,此时将temp(基准数)填入arr[i]中即完成算法的第2个步骤。接下来分别将基准数左边和右边的数组按照以上方法进行聚合,直到每个子集只有一个元素,即排序完成。

摘自 快速排序算法

个人理解

先找到一个标杆的数,然后两头有两列“巡检车”一样。从左边找到一个不符合的比这个标杆值大的,从右边找到一个比这个小的,然后将他们交换。等两列“巡检车”撞头的时候,就是排好序的位置。

当然中间有个小问题在于,如果说不把等号加入进比较的行列(也就是只考虑大于或者小于的情况)。可能会出现说,比如序列里面有两个标杆值,这样两个换来换去还是没法进行到下一步。

比如下面的代码

			while (l < r && arr[l] < pivotkey)
			{
				l++;
			}
			// 找到了一个不符合标准的左边数
			while (l < r && arr[r] > pivotkey)
			{
				r--;
			}
			// 找到了一个不符合标准的右边数
			dataSwap(arr, l, r);// 交换

遇到[2,2,2,2,2,2,2,3,3,3,1]这种就,没办法排序了,两个while会互相踢,谁也没办法进入下一个

解决办法就是。判断交换后的情况,如果交换后是标杆值,那强行往后拉对面的小车一下

while (l < r)
		{
			while (l < r && arr[l] < pivotkey)
			{
				l++;
			}
			// 找到了一个不符合标准的左边数
			while (l < r && arr[r] > pivotkey)
			{
				r--;
			}
			// 找到了一个不符合标准的右边数
			dataSwap(arr, l, r);// 交换

			// 如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
			if (arr[l] == pivotkey)
			{
				r -= 1;
			}
			// 如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
			if (arr[r] == pivotkey)
			{
				l += 1;
			}

		}

简单实现之

package sort;

import java.util.Arrays;

public class QuickSort
{

	public static void main(String[] args)
	{
		int[] arr =
		{ 5, 2,7,8,9, 3, 2, 1,4,6 };
		QSort(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(arr));

	}

	/**
	 * 递归调用
	 * 
	 * @param arr
	 */

	public static void QSort(int[] arr, int left, int high)
	{
		if (left < high)
		{
			int pivot = quickSort(arr, left, high);
			QSort(arr, left, pivot - 1);
			QSort(arr, pivot + 1, high);
		}

	}

	public static int quickSort(int[] arr, int left, int right)
	{
		// 关键值
		int index = (left + right) / 2;
		int pivotkey = arr[index];
		// 左指针
		int l = left;
		// 右指针
		int r = right;
		while (l < r)
		{
			while (l < r && arr[l] < pivotkey)
			{
				l++;
			}
			// 找到了一个不符合标准的左边数
			while (l < r && arr[r] > pivotkey)
			{
				r--;
			}
			// 找到了一个不符合标准的右边数
			dataSwap(arr, l, r);// 交换
			
			//1.防止后面递归数组越界
			//2.循环结束判断
			if (l >= r)
			{
				break;
			}

			// 如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
			if (arr[l] == pivotkey)
			{
				r -= 1;
			}
			// 如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
			if (arr[r] == pivotkey)
			{
				l += 1;
			}

		}

		return l;

	}

	public static void dataSwap(int[] arr, int first, int second)
	{

		int temp;
		temp = arr[first];
		arr[first] = arr[second];
		arr[second] = temp;

	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值