1. 程式人生 > >關於常用排序算法的一個總結

關於常用排序算法的一個總結

ons sta 一次 插入排序 臨時 class except 歸並 exception

  前段時間被人問到排序算法,今天特此總結一下,冒泡,選擇,快排,歸並,插入這五種排序算法。

  1.選擇排序

  選擇排序是整體對比,每次選出你最需要的那個值,比如以下代碼,首先選出最小的值,從小實現從小到大排序,外循環一次,內部循環記錄下最小的坐標,只發生一次交換,它是一種穩定的排序算法,時間復雜度為o(n2),核心代碼如下:

int[] numberArray = { 22, 32, 12, 1, 5, 66 };
		int arraylength = numberArray.length;
		int temp = 0;
		for (int i = 0; i < arraylength - 1; i++) {
			int k = i;
			for (int j = i + 1; j < arraylength; j++) {
				if (numberArray[k] > numberArray[j]) {
					k = j;
				}
			}

			if (i != k) {
				temp = numberArray[i];
				numberArray[i] = numberArray[k];
				numberArray[k] = temp;
			}
		}
		System.out.println(Arrays.toString(numberArray));

  2.冒泡排序

  冒泡排序的核心思路是相鄰元素進行對比,把大的數往後移,外循環一次,內部循環可能會發生很多次交換,它是一種穩定的算法,時間復雜度為o(n2),核心代碼如下:

int[] numberArray = { 22, 32, 12, 1, 5, 66 };
        int arraylength = numberArray.length;
        int temp = 0;
        for (int i = 0; i < arraylength - 1; i++) {
            for (int j = i + 1; j < arraylength; j++) {
                
if (numberArray[i] > numberArray[j]) { temp = numberArray[i]; numberArray[i] = numberArray[j]; numberArray[j] = temp; } } } System.out.println(Arrays.toString(numberArray));

  3.插入排序

  插入排序通過默認一個正確的位置,然後尋找插入位置,有點像我們完鬥地主時,會把連牌挨著大小放著,它也是一種穩定的排序算法,時間復雜度為o(n2

),核心代碼如下:

int[] numberArray = { 22, 32, 12, 1, 5, 66 };
		for (int i = 1; i < numberArray.length; i++) {
			////把j看作一個遊標
			int j = i;
			int target = numberArray[i];
			while (j > 0 && target < numberArray[j - 1]) {
				//// 說明有更大的,往後移
				numberArray[j] = numberArray[j - 1];
				j--;
			}

			numberArray[j] = target;
		}
		System.out.println(Arrays.toString(numberArray));

  4.快速排序

  快速排序的核心是冒泡+二分+遞歸分治,實際應用中算是最好的排序算法了,但它是一種不穩定的排序算法,平均時間復雜度為o(nlgn),最壞的情況是o(n2),它和冒泡算法的區別是同時查找大的數和小的數,核心代碼如下:

  

public static void main(String[] args) {
		try {
			int[] numberArray = new int[] { 4, 3, 6, 1, 2, 5 };
			recursionSort(numberArray, 0, numberArray.length - 1);
			System.out.println(Arrays.toString(numberArray));
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	private static void recursionSort(int[] numberArray, int low, int high) {
		if (low < high) {
			int basevalueIndex = partitionGroup(numberArray, low, high);
			////左區間遞歸
			recursionSort(numberArray, low, basevalueIndex - 1);
			////右區間遞歸
			recursionSort(numberArray, basevalueIndex + 1, high);
		}
	}

	private static int partitionGroup(int[] numberArray, int low, int high) {
		int basevalue = numberArray[low];
		while (low < high) {
			//// 先從右向左
			while (low < high && numberArray[high] >= basevalue) {
				--high;
			}
			//// 交換比基準值小的到左邊
			numberArray[low] = numberArray[high];
			while (low < high && numberArray[low] <= basevalue) {
				++low;
			}

			//// 交互比基準值大的到右邊
			numberArray[high] = numberArray[low];
		}

		//// 掃描完成,左右下標,即low=high
		numberArray[low] = basevalue;

		//// 返回基準值的下標
		return low;
	}

  5.歸並排序

  理論上歸並排序的效率應該高於快速排序,但是由於賦值次數較多以及分配臨時數組等,所以和快排的效率應該不相上下。它的思路就是把原始數組序列不斷兩兩分塊,直到每一個塊只剩下一個元素,然後利用遞歸的原理合並即可,它是一種穩定的排序算法,時間復雜度為o(n2),核心代碼如下:

  

public static void main(String[] args) {
		try {
			int[] numberArray = new int[] { 4, 3, 6, 1, 2, 5 };
			partition(numberArray, 0, numberArray.length - 1);
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	public static void partition(int[] a, int low, int high) {
		int mid = (low + high) / 2;
		if (low < high) {
			// 左邊
			partition(a, low, mid);
			// 右邊
			partition(a, mid + 1, high);
			// 左右歸並
			merge(a, low, mid, high);
			System.out.println(Arrays.toString(a));
		}

	}

	public static void merge(int[] numberArray, int low, int mid, int high) {
		int[] temp = new int[high - low + 1];
		//// 左指針
		int i = low;
		// 右指針
		int j = mid + 1;
		int k = 0;
		// 把較小的數先移到新數組中
		while (i <= mid && j <= high) {
			if (numberArray[i] < numberArray[j]) {
				temp[k++] = numberArray[i++];
			} else {
				temp[k++] = numberArray[j++];
			}
		}
		// 把左邊剩余的數移入數組
		while (i <= mid) {
			temp[k++] = numberArray[i++];
		}
		// 把右邊邊剩余的數移入數組
		while (j <= high) {
			temp[k++] = numberArray[j++];
		}
		// 把新數組中的數覆蓋nums數組
		for (int k2 = 0; k2 < temp.length; k2++) {
			numberArray[k2 + low] = temp[k2];
		}
	}

  

  

關於常用排序算法的一個總結