時間:2018-07-19 00:00:00 來源:信盈達 作者:信盈達
Java日常操作中常見的排序方法有:冒泡排序、快速排序、選擇排序、插入排序、希爾排序,甚至還有基數(shù)排序、雞尾酒排序、桶排序、鴿巢排序、歸并排序等。
以下常見算法的定義
1. 插入排序:插入排序基本操作就是將一個數(shù)據(jù)插入到已經(jīng)排好序的有序數(shù)據(jù)中,從而得到一個新的、個數(shù)加一的有序數(shù)據(jù),算法適用于少量數(shù)據(jù)的排序,時間復雜度為O(n^2)。是穩(wěn)定的排序方法。插入排序的基本思想是:每步將一個待排序的紀錄,按其關鍵碼值的大小插入前面已經(jīng)排序的文件中適當位置上,直到全部插入完為止。
2. 選擇排序:選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數(shù)據(jù)元素中選出最?。ɑ蜃畲螅┑囊粋€元素,存放在序列的起始位置,直到全部待排序的數(shù)據(jù)元素排完。 選擇排序是不穩(wěn)定的排序方法。
3. 冒泡排序:冒泡排序(Bubble Sort),是一種計算機科學領域的較簡單的排序算法。它重復地走訪過要排序的數(shù)列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數(shù)列的工作是重復地進行直到?jīng)]有再需要交換,也就是說該數(shù)列已經(jīng)排序完成。這個算法的名字由來是因為越大的元素會經(jīng)由交換慢慢“浮”到數(shù)列的頂端。
4. 快速排序:快速排序(Quicksort)是對冒泡排序的一種改進。它的基本思想是:通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨立的兩部分,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小,然后再按此方法對這兩部分數(shù)據(jù)分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數(shù)據(jù)變成有序序列。
5. 歸并排序:歸并排序是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表,稱為二路歸并。
6. 希爾排序:希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩(wěn)定排序算法。希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。
一、冒泡排序
冒泡排序是一種簡單的排序算法。它重復地走訪過要排序的數(shù)列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數(shù)列的工作是重復地進行直到?jīng)]有再需要交換,也就是說該數(shù)列已經(jīng)排序完成。這個算法的名字由來是因為越小的元素會經(jīng)由交換慢慢“浮”到數(shù)列的頂端。
/** * 冒泡法排序 * 比較相鄰的元素。如果第一個比第二個小,就交換他們兩個。 * 對每一對相鄰元素作同樣的工作,從開始第一對到結(jié)尾的最后一對。在這一點,最后的元素應該會是最小的數(shù)。 * 針對所有的元素重復以上的步驟,除了最后一個。 * 持續(xù)每次對越來越少的元素重復上面的步驟,直到?jīng)]有任何一對數(shù)字需要比較。 * * @param numbers * 需要排序的整型數(shù)組 */ public static void bubbleSort01(int[] numbers) { int temp; // 記錄臨時中間值 int size = numbers.length; // 數(shù)組大小 for (int i = 0; i < size - 1; i++) { for (int j = i + 1; j < size; j++) { if (numbers[i] < numbers[j]) { // 交換兩數(shù)的位置 temp = numbers[i]; numbers[i] = numbers[j]; numbers[j] = temp; } } } }
注意:以上不知是什么排序,將基準位置的元素和后面的元素進行比較,如果基準位置值比后面元素小,則交換位置,交換后的元素為新的基準元素。以下才是真正的冒泡排序。
public static void bubbleSort(int[] a) { int temp; int size = a.length; for(int i=1; i
二、快速排序
快速排序使用分治法策略來把一個序列分為兩個子序列。
/** * 快速排序 * * 從數(shù)列中挑出一個元素,稱為“基準” * 重新排序數(shù)列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的后面(相同的數(shù)可以到任一邊)。在這個分割之后, * 該基準是它的最后位置。這個稱為分割(partition)操作。 * 遞歸地把小于基準值元素的子數(shù)列和大于基準值元素的子數(shù)列排序。 * * @param numbers * @param start * @param end */ public static void quickSort(int[] numbers, int start, int end) { if (start < end) { int base = numbers[start]; // 選定的基準值(第一個數(shù)值作為基準值) int temp; // 記錄臨時中間值 int i = start, j = end; do { while ((numbers[i] < base) && (i < end)) i++; while ((numbers[j] > base) && (j > start)) j--; if (i <= j) { temp = numbers[i]; numbers[i] = numbers[j]; numbers[j] = temp; i++; j--; } } while (i <= j); if (start < j) quickSort(numbers, start, j); if (end > i) quickSort(numbers, i, end); } }
如下為完全符合快速排序定義的算法:
public static void quickSort01(int[] a, int start, int end) { if(start >= end) return; int i = start; int j = end; int base = a[start]; while(i != j) { while(a[j] >= base && j > i) j--; while(a[i] <= base && i < j) i++; if(i < j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } } a[start] = a[i]; a[i] = base; te(a, start, i - 1); te(a, i + 1, end); }
三、選擇排序
選擇排序是一種簡單直觀的排序方法,每次尋找序列中的最小值,然后放在最末尾的位置。
/** * 選擇排序 * 在未排序序列中找到最小元素,存放到排序序列的起始位置 * 再從剩余未排序元素中繼續(xù)尋找最小元素,然后放到排序序列起始位置。 * 以此類推,直到所有元素均排序完畢。 * * @param numbers */ public static void selectSort(int[] numbers) { int size = numbers.length; int temp; for (int i = 0; i < size; i++) { int k = i; for (int j = size - 1; j >i; j--) { if (numbers[j] < numbers[k]) { k = j; } } temp = numbers[i]; numbers[i] = numbers[k]; numbers[k] = temp; } }
四、插入排序
插入排序的工作原理是通過構(gòu)建有序序列,對于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應位置并插入。其具體步驟參見代碼及注釋。
/** * 插入排序 * * 從第一個元素開始,該元素可以認為已經(jīng)被排序 * 取出下一個元素,在已經(jīng)排序的元素序列中從后向前掃描 * 如果該元素(已排序)大于新元素,將該元素移到下一位置 * 重復步驟3,直到找到已排序的元素小于或者等于新元素的位置 * 將新元素插入到該位置中 * 重復步驟2 * @param numbers */ public static void insertSort(int[] numbers) { int size = numbers.length, temp, j; for(int i=1; i0 && temp < numbers[j-1]; j--) numbers[j] = numbers[j-1]; numbers[j] = temp; } }
五、歸并排序
歸并排序是建立在歸并操作上的一種有效的排序算法,歸并是指將兩個已經(jīng)排序的序列合并成一個序列的操作。
/** * 歸并排序 * * 申請空間,使其大小為兩個已經(jīng)排序序列之和,該空間用來存放合并后的序列 * 設定兩個指針,最初位置分別為兩個已經(jīng)排序序列的起始位置 * 比較兩個指針所指向的元素,選擇相對小的元素放入到合并空間,并移動指針到下一位置 * 重復步驟3直到某一指針達到序列尾 * 將另一序列剩下的所有元素直接復制到合并序列尾 * * @param numbers */ public static void mergeSort(int[] numbers, int left, int right) { int t = 1;// 每組元素個數(shù) int size = right - left + 1; while (t < size) { int s = t;// 本次循環(huán)每組元素個數(shù) t = 2 * s; int i = left; while (i + (t - 1) < size) { merge(numbers, i, i + (s - 1), i + (t - 1)); i += t; } if (i + (s - 1) < right) merge(numbers, i, i + (s - 1), right); } } /** * 歸并算法實現(xiàn) * * @param data * @param p * @param q * @param r */ private static void merge(int[] data, int p, int q, int r) { int[] B = new int[data.length]; int s = p; int t = q + 1; int k = p; while (s <= q && t <= r) { if (data[s] <= data[t]) { B[k] = data[s]; s++; } else { B[k] = data[t]; t++; } k++; } if (s == q + 1) B[k++] = data[t++]; else B[k++] = data[s++]; for (int i = p; i <= r; i++) data[i] = B[i]; }
信盈達2008年在深圳特區(qū)南山高新科技園成立。自成立至今近九年來專注為企業(yè)和個人提供高端方案設計、高端嵌入式/Android培訓等服務。公司下設信盈達實訓學院、信盈達研發(fā)中心、信盈達教學儀器三大業(yè)務板塊。九年來公司堅持"技術(shù)領先、服務領先",以雄厚的實力和專業(yè)的品質(zhì)成為國內(nèi)唯一有實力從產(chǎn)品最底層研發(fā)到系統(tǒng)層開發(fā)的嵌入式實訓、產(chǎn)品解決方案提供商。為中國IT行業(yè)提供最具價值的職業(yè)教育服務。專業(yè)培訓i嵌入式、物聯(lián)網(wǎng)、人工智能、Java、單片機等課程,想了解更多信息點擊立馬咨詢
免費領取試聽卡
申請已經(jīng)提交
老師會馬上給您安排試聽課程!
申請出錯了
您可以加老師QQ:914865590報名咨詢!