Java 常見排序算法

1、排序算法

冒泡排序

雞尾酒排序

選擇排序

直接插入排序

歸併排序

堆排序

快速排序

2、示例代碼

public class Sort {

	public static void main(String[] args) {
		int a[] = { 10, 90, 20, 80, 30, 70, 40, 50, 60 };
		System.out.println("初始數據:" + Arrays.toString(a));
		bubbleSort(a);					// 冒泡排序
		cocktailSort(a);				// 雞尾酒排序
		selectionSort(a);				// 選擇排序
		insertSort1(a);					// 直接插入排序
		insertSort2(a);					// 直接插入排序
		mergeSort(a, 0, a.length-1);	// 歸併排序
		heapSort(a);					// 堆排序
		quickSort(a, 0, a.length-1);	// 快速排序
	}
	
	/**
	 * 
	 * 方法描述:冒泡排序
	 * 它重複地走訪過要排序的元素列,依次比較相鄰的元素,如果他們的順序錯誤就把他們交換過來。
	 * 
	 * @param a 數組數據
	 * 
	 */
	public static void bubbleSort(int[] a) {
		int n = a.length;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n - 1; j++) {
				int swap1 = 0;
				int swap2 = 0;
				if (a[j] > a[j + 1]) {
					swap1 = a[j];
					swap2 = a[j + 1];
					swap(a, j, j + 1);
				}
				System.out.println("交換位置:" + j + "-----交換數據:" + swap1 + "," + swap2 + "-----交換結果:" + Arrays.toString(a));
			}
			System.out.println("第" + i + "次排序結果:" + Arrays.toString(a));
		}
	}
	
	/**
	 * 
	 * 方法描述:雞尾酒排序
	 * 雙向冒泡排序,排序時雙向在隊列中進行排序。
	 *
	 * @param a	
	 * 
	 */
	public static void cocktailSort(int[] a) {
		int left = 0;
		int right = a.length - 1;
		for (int i = left; i < right; i++) {
			for (int j = left; j < right; j++) {
				int swap1 = 0;
				int swap2 = 0;
				if (a[j] > a[j + 1]) {
					swap1 = a[j];
					swap2 = a[j + 1];
					swap(a, j, j + 1);
				}
				System.out.println("左交換位置:" + j + "-----交換數據:" + swap1 + "," + swap2 + "-----交換結果:"
						+ Arrays.toString(a));
			}
			left++;
			for (int j = right - 1; j > left; j--) {
				int swap1 = 0;
				int swap2 = 0;
				if (a[j] > a[j + 1]) {
					swap1 = a[j];
					swap2 = a[j + 1];
					swap(a, j, j + 1);
				}
				System.out.println("右交換位置:" + j + "-----交換數據:" + swap1 + "," + swap2 + "-----交換結果:"
						+ Arrays.toString(a));
			}
			right--;
			System.out.println("第" + i + "次排序結果:" + Arrays.toString(a));
		}
	}
	
	/**
	 * 
	 * 方法描述:選擇排序
	 * 第一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然後再從剩餘的未排序元素中尋找到最小(大)元素,然後放到已排序的序列的末尾。
	 * 以此類推,直到全部待排序的數據元素的個數爲零。
	 * 選擇排序是不穩定的排序方法。
	 *
	 * @param a
	 * 
	 */
	public static void selectionSort(int[] a) {
		int min;
		int max;
		int count = a.length;
		for (int i = 0; i < count; i++) {
			min = i;
			max = count - 1;
			for (int j = i; j < count; j++) {
				if (a[min] > a[j]) {
					min = j;
				}
				if (a[max] < a[j]) {
					max = j;
				}
			}
			if (min != i) {
				System.out.println("min交換位置:"+max+","+i+"-----交換數據:"+a[min]+","+a[i]+"-----min排序前:" + Arrays.toString(a));
				swap(a, min, i);
				System.out.println("min排序後:" + Arrays.toString(a));
			}
			if (max != count-1) {
				System.out.println("max交換位置:"+max+","+(count-1)+"-----交換數據:"+a[max]+","+a[count-1]+"-----max排序前:" + Arrays.toString(a));
				swap(a, max, count-1);
				System.out.println("max排序後:" + Arrays.toString(a));
			}
			count--;
			System.out.println("第" + i + "次排序結果:" + Arrays.toString(a));
		}
	}
	
	/**
	 * 
	 * 方法描述:直接插入排序
	 * 將一條記錄插入已經排好的有序表中,從而得到一個新的、記錄數量增1的有序表
	 *
	 * @param a
	 * 
	 */
	public static void insertSort(int[] a) {
		for (int i = 1; i < a.length; i++) {	// 第0位獨自作爲有序數列,從第1位開始向後遍歷
			if (a[i]<a[i-1]) {					// 第0~i-1位爲有序位,若第i位小於i-1位,繼續尋位並插入,否則認爲0~i位是有序的,忽略此次
				int temp = a[i];
				int k = i -1;
				for (int j = k; j>0 && temp<a[j]; j--) {	// 從第i-1位向前遍歷,直至找到小於第i位值停止
					a[j+1] = a[j];
					k--;
				}
				a[k+1] = temp;
			}
			System.out.println("第" + i + "次排序結果:" + Arrays.toString(a));
		}
	}
	
	/**
	 * 
	 * 方法描述:直接插入排序
	 *
	 * @param arr
	 * @return
	 * 
	 */
	public static void insertSort1(int[] a) {
		for (int i = 1; i < a.length; i++) {
			for (int j = i; j > 0; j--) {
				if (a[j] < a[j - 1]) {
					int temp = a[j];
					a[j] = a[j - 1];
					a[j - 1] = temp;
				}
			}
			System.out.println("第" + i + "次排序結果:" + Arrays.toString(a));
		}
	}
	
	/**
	 * 
	 * 方法描述:直接插入排序
	 *
	 * @param a
	 * 
	 */
	public static void insertSort2(int[] a) {
		for (int i = 1; i < a.length; i++) {
			int temp = a[i];
			int index = 0;
			for (int j = i; j > 0; j--) {
				if (a[j] < a[j - 1]) {
					a[j] = a[j - 1];
					index = j - 1;
				}
				a[index] = temp;
			}
			System.out.println("第" + i + "次排序結果:" + Arrays.toString(a));
		}
	}
	
	/**
	 * 
	 * 方法描述:歸併排序
	 * 將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。
	 *
	 * @param a
	 * @param l
	 * @param h
	 * @return
	 * 
	 */
	public static int[] mergeSort(int[] a, int l, int h) {
		if (l == h) {
			return new int[] {a[l]};
		}
		int mid = l + (h - l) / 2;
		int[] leftA = mergeSort(a, l, mid);
		int[] rightA = mergeSort(a, mid+1, h);
		int[] newNum = new int[leftA.length + rightA.length];
		
		int m=0, i=0, j=0;
		while(i < leftA.length && j < rightA.length) {
			newNum[m++] = leftA[i] < rightA[j] ? leftA[i++] : rightA[j++];
		}
		while(i < leftA.length) {
			newNum[m++] = leftA[i++];
		}
		while(j < rightA.length) {
			newNum[m++] = rightA[j++];
		}
		System.out.println("排序結果:" + Arrays.toString(newNum));
		return newNum;
	}
	
	/**
	 * 
	 * 方法描述:堆排序
	 *
	 * @param a
	 * @return
	 * 
	 */
	public static int[] heapSort(int[] a){
		for (int i = a.length / 2 - 1; i >= 0; i--) {
			adjustHeap(a, i, a.length);
		}
		for (int j = a.length - 1; j > 0; j--) {
			swap(a, 0, j);
			adjustHeap(a, 0, j);
			System.out.println("排序結果:" + Arrays.toString(a));
		}
		return a;
	}
	
	/**
	 * 
	 * 方法描述:
	 *
	 * @param a		待組堆
	 * @param i		起始點
	 * @param length堆長度
	 * 
	 */
	public static void adjustHeap(int[] a, int i, int length) {
		int temp = a[i];
		for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {
			if (k + 1 <length && a[k] < a[k + 1]) {
				k++;
			}
			if (a[k] > temp) {
				swap(a, i, k);
				i = k;
			} else {
				break;
			}
		}
	}
	
	/**
	 * 
	 * 方法描述:快速排序
	 * 通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小。
	 * 然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
	 *
	 * @param a
	 * 
	 */
	public static int[] quickSort(int[] a, int start, int end) {
		int pivot = a[start];
		int i = start;
		int j = end;
		while (i < j) {
			while ((i < j) && (a[j] > pivot)) {
				j--;
			}
			while ((i < j) && (a[i] < pivot)) {
				i++;
			}
			if ((a[i] == a[j]) && (i < j)) {
				i++;
			} else {
				swap(a, i, j);
			}
		}
		System.out.println("起始位置 " + start + " 到終止位置 " + end + " 的排序結果:" + Arrays.toString(a));
		if (i - 1 > start)
			a = quickSort(a, start, i - 1);
		if (j + 1 < end)
			a = quickSort(a, j + 1, end);
		return a;
	}
	
	/**
	 * 
	 * 方法描述:相鄰元素交換位置
	 * 
	 * @param a
	 * @param i
	 * @param j
	 * 
	 */
	public static void swap(int[] a, int i, int j) {
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
	
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章