1. 程式人生 > >Java-經典排序演算法(一)

Java-經典排序演算法(一)

前言:

排序演算法有很多種,如選擇排序、插入排序、氣泡排序、桶排序、快速排序等等。這裡介紹的是簡化版桶排序、氣泡排序和插入排序。 推薦一本演算法入門書——《啊哈!演算法》

1. 桶排序[簡化版]:

原理:新建一個book陣列用來標記原陣列每一個數字出現的個數。

	public static int[] bottomSort(int[] nums) {
		int[] res = new int[nums.length];
		int temp = nums[0];
		for (int lang : nums)
			temp = Math.max(temp, lang);
		int[] book = new int[temp + 1];
		for (int i = 0; i < nums.length; i++) {
			book[nums[i]]++;
		}
		int z = 0;
		for (int i = 0; i <= book.length - 1; i++) { //由小到大排序。
			for (int j = 1; j <= book[i]; j++) {
				res[z] = i;
				z++;
			}
		}
		return res;
	}

桶排序的優缺點:

優點:

時間複雜度為O(M+N),執行非常快速。

缺點:

1.由於book陣列的大小由原陣列中最大值決定,因此非常地浪費空間。

2.只能處理int型陣列,不能處理float/double型陣列。


2.氣泡排序

氣泡排序所用程式碼最少,易於理解和記憶,所以使用最是頻繁。

氣泡排序的基本思想是:每次比較兩個相鄰的元素,如果它們的順序錯誤就把它們交換過來.氣泡排序的核心部分是雙重巢狀迴圈。

	public static void bubbleSort(int[] nums) {
		
		for (int i = 0; i < nums.length; i++) {
			for (int j = 0; j < nums.length; j++) {
				if (nums[i] < nums[j] && i > j) {
					int temp = nums[i];
					nums[i] = nums[j];
					nums[j] = temp;
				}
			}
		}
	}


氣泡排序優缺點:

優點:

程式碼量少,易於使用。

缺點:

氣泡排序的時間複雜度是O(N^2)。這是一個非常高的時間複雜度。

假如我們的計算機每秒鐘可以執行10億次,那麼對1億個數進行排序,桶排序只需要0.1秒,而氣泡排序則需要1千萬秒(引用自《啊哈!演算法》)


3. 插入排序:

插入排序基本思想:

插入演算法把要排序的陣列分成兩部分:第一部分包含了這個陣列的所有元素,但將最後一個元素除外(讓陣列多一個空間才有插入的位置),而第二部分就只包含這一個元素(即待插入元素)。在第一部分排序完成後,再將這個最後元素插入到已排好序的第一部分中。插入排序的基本思想是:每步將一個待排序的紀錄,按其關鍵碼值的大小插入前面已經排序的檔案中適當位置上,直到全部插入完為止。

	public static int[] InsertSort(int[] arr) {
		int i, j;
		int insertNote;// 要插入的資料
		int[] array = arr;
		// 從陣列的第二個元素開始迴圈將陣列中的元素插入
		for (i = 1; i < array.length; i++) {
			// 設定陣列中的第2個元素為第一次迴圈要插入的資料
			insertNote = array[i];
			j = i - 1;
			while (j >= 0 && insertNote < array[j]) {
				// 如果要插入的元素小於第j個元素,就將第j個元素向後移動
				array[j + 1] = array[j];
				j--;
			}
			// 直到要插入的元素不小於第j個元素,將insertNote插入到陣列中
			array[j + 1] = insertNote;
		}
		return array;
	}

插入排序的時間複雜度也是O(n^2),另外選擇排序也是。插入排序和氣泡排序的思想其實是相似的,通過將大小不同的兩個值對調索引來實現排序,不過插入排序相對於氣泡排序而言所用時間應該更少一點。

推薦一篇講解插入排序的部落格:

http://www.cnblogs.com/xiaoming0601/p/5862793.html