java实现快速排序一种常规的,一种是左程云的方式。

本文深入解析Java实现的快速排序算法,包括常规快排、改进版快排及左程云方式的快排。通过代码示例详细说明不同版本的实现细节与优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java实现快速排序:

一:先来一个常规快排:

这个方式就是我们的基准值一直在两个边界徘徊,要么在less的较大边界,要么是在more的小边界,其实就是在居中位置徘徊。

package chapter1;



//来一个快排,常规快排
public class QuickSort {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 7, 5, 4, 3, 9, 2, 7 };
		System.out.print("排序前     ");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+"  ");
		}
		System.out.println();
		quickSort(arr, 0, arr.length-1);
		System.out.print("排序后     ");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+"  ");
		}
	}

	public static void quickSort(int[] arr, int low, int high) {
		if (low < high) {//找出分割点,然后左分割,右分割
			int patition = patition(arr, low, high);
			quickSort(arr, low, patition-1);
			quickSort(arr, patition + 1, high);
		}
	}

	public static int patition(int[] arr, int low, int high) {
		int num = arr[low];// 我们取第一个作为基准值,而且基准值开始是在最低位
		while (low < high) {
			while (low < high && arr[high] > num) {
				high--;
			}
			swap(arr, low, high);//交换后,基准值跑到高位较小的位置了
			while (low < high && arr[low] <= num) {
				low++;
			}
			swap(arr, low, high);//交换后,基准值又跑到低位较大位置了
			
		}
		return low;

	}

	private static void swap(int[] arr, int low, int high) {
		int temp = arr[low];
		arr[low] = arr[high];
		arr[high] = temp;

	}
}

控制台打印如下:

下边一个和上边一个一样,只是有细微区别:

package sort;

public class QuickSort {
	public static void main(String[] args) {
		int[] arr = { 7, 2, 3, 5, 4, 6 };
		quickSort(arr, 0, arr.length - 1);
		for (int i = 0; i < arr.length; i++) {
			System.out.print("  " + arr[i] + "  ");
		}
	}

	public static void quickSort(int[] arr, int small, int big) {
		// 来一个终止条件
		if (small >= big) {// 这个终止条件,不能是small==big,是因为在下边的左边来一波和右边来一波中,可能存在small大于big的
			return;
		}
		// 首先是找出分割点
		int mid = partition(arr, small, big);
		// 左边来一波
		quickSort(arr, small, mid - 1);
		// 右边来一波
		quickSort(arr, mid + 1, big);
	}

	private static int partition(int[] arr, int small, int big) {
		int num = arr[small];
		while (small < big) {
			while (small < big && num <= arr[big]) {
				big--;
			}
			swap(arr, small, big);
			while (small < big && num > arr[small]) {
				small++;
			}
			swap(arr, small, big);
		}
		return small;
	}

	private static void swap(int[] arr, int small, int big) {
		int temp = arr[small];
		arr[small] = arr[big];
		arr[big] = temp;

	}

}

控制台:

改进版本:就是添加了排除相等部分的重复排序:区别就是在左边和右边开始的时候,取的边界不一样

package chapter1;

//来一个快排,改进快排,我们多添加一个记录想等值。
public class QuickSort {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 7, 5, 4, 3, 9, 2, 7 };
		System.out.print("排序前     ");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + "  ");
		}
		System.out.println();
		quickSort(arr, 0, arr.length - 1);
		System.out.print("排序后     ");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + "  ");
		}
	}

	public static void quickSort(int[] arr, int low, int high) {
		if (low < high) {
			int[] patition = patition(arr, low, high);
			quickSort(arr, low, patition[0] - patition[1]);
			quickSort(arr, patition[0] + 1, high);
		}
	}

	public static int[] patition(int[] arr, int low, int high) {
		int num = arr[low];// 我们取第一个作为基准值
		int equal = 0;// 这个用来记录等于基准值的数量,至少是1
		int result[] = new int[2];
		while (low < high) {
			while (low < high && arr[high] > num) {
				high--;
			}
			swap(arr, low, high);
			while (low < high && arr[low] <= num) {
				if (arr[low] == num) {
					equal++;
				}
				low++;
			}

			swap(arr, low, high);

		}
		result[0] = low;
		result[1] = equal;
		return result;

	}

	private static void swap(int[] arr, int low, int high) {
		int temp = arr[low];
		arr[low] = arr[high];
		arr[high] = temp;

	}
}

控制台:

二:左程云方式的快排

其实就是多了一部分,多了指出相等值的那部分,第二次就不需要再去重复排那些相等值的过程

 

首先来看一个问题:我们快排第一步是找一个基准值 ,然后右边值都大于基准值,左边值都小于基准值。

题目一:我随意给定一个数组和一个给定值,大于该值放右边,其他放左边,同时不能使用多余数组

package chapter1;

//需求:给一个数组,和其中一个数,将大于这个数和小于这个数的分成两边
public class GroupTest {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 7, 5, 4, 3, 9, 2, 7 };
		int num = 6;
		group(arr, num);
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]);
		}
	}

	public static void group(int[] arr, int num) {
		int p = 0;
		int small = 0;// 小数的边界
		int big = arr.length - 1;// 大数的边界
		while (small < big) {
			if (arr[p] < num) {
				exchange(arr, small, p);
				small++;
				p++;
			} else {
				exchange(arr, big, p);
				big--;

			}

		}
	}

	private static void exchange(int[] arr, int q, int p) {
		// TODO Auto-generated method stub
		int temp = arr[p];
		arr[p] = arr[q];
		arr[q] = temp;
	}
}

控制台:

 

通常我们选取最后一个或者第一个值为我们的基准值。下边我们选取最后一个值作为基准值,而且如果我们使用了把中间值拿过来放着后边不做比较,那么我们比较次数会更少一点

题目二:给定一个整型数组,然后以最后一个数为基准,将大于基准值的放右边,小于基准值放到左边。最后数组的情况就是,在基准值两边,一边是全部大于基准值,一边是全部小于基准值;

我们使用三个指针来区分三块,一块是小于区域,中间是等于区域,右边是大于区域。开始的时候,小于和大于区域都是在数组外边,要是存在一个符合要求的,就放到相应区域,同时该区域长度就增加1。如果是有一个小于的,首先交换当前值和less后边那个值,那么小于的区域的指针就++less,同时也会推着中间部分往右边跑,所以当前指针cur++;如果是满足大于区域,就把当前cur指向的数和大于那边的区域的边界more前边的那个数值交换,同时大于区域增加,就是--more,但是这里我们的cur就不变化。

 

 

 

代码:

package test2018926;

public class QuickSort {
	public static void main(String[] args) {
		Integer[] arr = { 1, 2, 7, 5, 4, 3 };
		partition(arr, 0, arr.length - 1);
	}

	public static Integer[] partition(Integer[] arr, int L, int R) {

		// 使用三个指针来将我们的数据分成三类,
		int cur = L;// 这个指向当前数据
		int less = L - 1;// 小数的前面一个
		int more = R + 1;// 大数的后边一个
		int num = arr[arr.length - 1];// 以最后一个值为基准来排出大于和小于
		Integer[] arr1 = new Integer[2];
		while (cur < more) {
			// System.out.println(cur);
			if (arr[cur] > num) {
				swap(arr, cur, --more);
			} else if (arr[cur] < num) {
				swap(arr, cur++, ++less);// less位置增加一个,就会推着cur向后
			} else {
				cur++;
			}
		}
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]);
		}
		arr1[0] = less + 1;//等于num的左边界
		arr1[1] = more - 1;//等于num的右边界
		return arr1;
	}

	// 交换数组位置
	private static void swap(Integer[] arr, Integer m, Integer n) {
		int temp = arr[m];
		arr[m] = arr[n];
		arr[n] = temp;
	}
}

控制台打印:

 

 

题目三:下边讲解我们的改进快排:

快排就是不断细分,对一个小部分都进行上边相同的操作。

开始分为两边,然后对两边分别再分两边,一直分到最小,就是分成单个为止。

package test2018926;

public class QuickSort {
	public static void main(String[] args) {
		Integer[] arr = { 1, 2, 7, 5, 4, 3 };
		quickSort(arr, 0, arr.length - 1);
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]);
		}
	}

	public static void quickSort(Integer[] arr, int L, int R) {
		if (L < R) {
			Integer[] p = partition(arr, L, R);// 返回的是相同数值区域的两个边界
			quickSort(arr, L, p[0] - 1);//p[0]是等于部分的左边界
			quickSort(arr, p[1] + 1, R);//p[1]是等于部分的右边界

		}

	}

	public static Integer[] partition(Integer[] arr, int L, int R) {

		// 使用三个指针来将我们的数据分成三类,
		int cur = L;// 这个指向当前数据
		int less = L - 1;// 小数的前面一个
		int more = R + 1;// 大数的后边一个
		int num = arr[arr.length - 1];// 以最后一个值为基准来排出大于和小于
		Integer[] arr1 = new Integer[2];
		while (cur < more) {
			// System.out.println(cur);
			if (arr[cur] > num) {
				swap(arr, cur, --more);
			} else if (arr[cur] < num) {
				swap(arr, cur++, ++less);// less位置增加一个,就会推着cur向后
			} else {
				cur++;
			}
		}
		for (int i = 0; i < arr.length; i++) {
			// System.out.print(arr[i]);
		}
		arr1[0] = less + 1;
		arr1[1] = more - 1;
		return arr1;
	}

	// 交换数组位置
	private static void swap(Integer[] arr, Integer m, Integer n) {
		int temp = arr[m];
		arr[m] = arr[n];
		arr[n] = temp;
	}
}

控制台打印:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值