標籤:
看了幾天的排序內容,現在和大家分享一些常見的排序方法。
啥是排序?
個人理解的排序:通過對數組中的值進行對比,交換位置最終得到一個有序的數組。排序分為記憶體排序和外部排序。本次分享排序方法都為記憶體排序。
啥是排序的穩定性?
假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,ri=rj,且ri在rj之前,而在排序後的序列中,ri仍在rj之前,則稱這種排序演算法是穩定的;否則稱為不穩定的。
常見排序:
冒泡排序,選擇排序,直接插入排序,希爾排序,堆排序,歸併排序,快速排序。
來張圖展示一下種排序的關係:
排序思想:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。
複雜度:O(n^2)。
穩定性:穩定。
冒泡排序是我最早接觸的排序演算法,理解起來比較簡單。排序入門級,容易理解,通過不斷交換位置來排序。
代碼執行個體:
int[] list = { 50, 10, 90, 30, 70, 40, 20 };int temp;for (int i = 0; i < list.Length; i++){ for (int j = i + 1; j < list.Length; j++) { if (list[i] > list[j]) { temp = list[i]; list[i] = list[j]; list[j] = temp; } }}Console.WriteLine("冒泡排序的結果:{0}", string.Join(",", list));
第一個for迴圈取資料中一個值list[i],第二個for迴圈已第一個for迴圈中的下一個值(j=i+1)開始取值list[j]。然後依次對比兩值的大小list[i] > list[j],如果數組中前面的值大於後面的值,替換他兩的位置。始終保持數組中左邊的值小於右邊的值。
冒泡排序還有其他很多版本這裡就不一一分享。
| 選擇排序 (Simple Selection Sort) |
排序思想:每一趟在n-i+1(i=1,2,…n-1)個記錄中選取關鍵字最小的記錄作為有序序列中第i個記錄。
複雜度:O(n^2)。
穩定性:穩定。
代碼執行個體:
int[] list = { 50, 10, 90, 30, 70, 40, 20 };int minIndex, temp;for (int i = 0; i < list.Length; i++){ minIndex = i; /*把當前迴圈的值認為是最小值*/ for (int j = i + 1; j < list.Length; j++) { if (list[j] < list[minIndex]) { minIndex = j; /*進過N次迴圈我們找到最小值並賦值給minIndex*/ } } if (minIndex!=i) { temp = list[minIndex]; /*把當前迴圈出的最小值和list[i]替換。實現左邊資料比右邊資料要小*/ list[minIndex] = list[i]; list[i] = temp; }}Console.WriteLine("選擇排序的結果:{0}", string.Join(",", list));
第一個for迴圈數組中元素list[i],把當前迴圈的值預設為是最小值。記錄下標賦值給minIndex。第二個for迴圈已第一個for迴圈中的下一個值(j=i+1)開始取值list[j]。然後依次和list[minIndex]對比,如果list[j]<list[minIndex]把迴圈中j的下標賦值給minIndex(保持minIndex為迴圈中最小值的下標)。到第二個for迴圈結束,然後替換當前迴圈的值list[i]和list[minIndex]的位置。始終保持數組中左邊的值小於右邊的值。
選擇排序相對冒泡排序交換位置次數少,排序效能略優冒泡排序。
| 直接插入排序 (Straight Insertion Sort) |
排序思想:
每次從無序表中取出第一個元素,把它插入到有序表的合適位置,使有序表仍然有序。
第一趟比較前兩個數,然後把第二個數按大小插入到有序表中;
第二趟把第三個資料與前兩個數從前向後掃描,把第三個數按大小插入到有序表中;依次進行下去,進行了(n-1)趟掃描以後就完成了整個排序過程。
複雜度:O(n^2)。
穩定性:穩定。
代碼執行個體:
int[] list = { 50, 10, 90, 30, 70, 40, 20 };int temp, j;for (int i = 1; i < list.Length; i++) /*從資料第二位開始迴圈 [無序序列] */{ if (list[i] < list[i - 1]) { temp = list[i]; for (j = i - 1; j >= 0 && temp < list[j]; j--) /*[有序序列] */ { list[j + 1] = list[j]; } list[j + 1] = temp; }}Console.WriteLine("直接插入排序的結果:{0}", string.Join(",", list));
第一個for迴圈(從數組第二位置開始迴圈)數組中元素list[i],如果迴圈的當前值list[i]比數組中上一個值list[i-1]要小,聲明臨時變數temp記錄list[i]。然後根據第一個for迴圈的i值,反向迴圈數組,查詢小於list[i]的下標位置。然後替換list[j+1]的值。
C# 資料結構--排序[上]