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

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 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;
	}
}

控制台打印:

猜你喜欢

转载自blog.csdn.net/Handsome2013/article/details/82858209