1. 程式人生 > >java實現快速排序一種常規的,一種是左程雲的方式。

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

控制檯列印: