C# 数据结构--排序[下]
希爾排序(Shell Sort)
排序思想:
先取一個小于n的整數d1作為第一個增量,把文件的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然后,取第二個增量d2<d1重復上述的分組和排序,直至所取的增量 dt=1(dt<dt-1…<d2<d1),即所有記錄放在同一組中進行直接插入排序為止。
復雜度:O(n3/2)。
穩定性:不穩定。
代碼實例:
int[] list = { 50, 10, 90, 30, 70, 40, 20 }; int len = list.Length; int temp, j; while (len > 1) {len = len / 2;for (int i = len; i < list.Length; i++){if (list[i] < list[i - len]){temp = list[i];for (j = i - len; j >= 0 && temp < list[j]; j = j - len){list[j + len] = list[j];}list[j + len] = temp;}} } Console.WriteLine("希爾排序的結果:{0}",string.Join(",", list));堆排序(Heap Sort?)
排序思想:指利用堆積樹(堆)這種數據結構所設計的一種排序算法,它是選擇排序的一種。
堆是具有下列性質的完全二叉樹:每個結點的值都大于或等于其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小于或等于其左右孩子結點的值,稱為小頂堆。
復雜度:O(nlogn)。
穩定性:不穩定。
?
堆排序只用做以下二點:
1:從無序序列中構建起大頂堆。
2:交換大頂堆中頂節點和后結點(n)位置,重新調整剩余元素,構建一個新的大頂堆。依次循環....
代碼實例:
static void Main(string[] args) {int[] list = { 50, 10, 90, 30, 70, 40, 20 };for (int i = list.Length / 2 - 1; i >= 0; i--) /* 構建大頂堆[list.Length / 2 - 1:無序數組中結點數]*/{HeapAdjust(list, i, list.Length);}int temp;for (int i = list.Length - 1; i > 0; i--) /* 替換大頂堆的位置,然后重新構建大頂堆。*/{temp = list[0]; /* 替換大頂堆中最大值list[0]和最小值之前的位置list[i]*/list[0] = list[i];list[i] = temp;HeapAdjust(list, 0, i); /* 重新構建大頂堆*/}Console.WriteLine("堆排序的結果:{0}", string.Join(",", list)); }/// <summary> /// 構建大頂堆 /// </summary> /// <param name="list">排序集合</param> /// <param name="NodeIndex">父結點</param> /// <param name="len">大頂堆長度</param> static void HeapAdjust(int[] list, int NodeIndex, int len) {int temp = list[NodeIndex]; /*二叉樹節點值*/for (int i = NodeIndex * 2 + 1; i < len; i = NodeIndex * 2 + 1) /*循環二叉樹節點下左右孩子[NodeIndex*2+1找到結點下的左右孩子]*/{if (i + 1 < len && list[i] < list[i + 1]) /*i+1:是否存在左右兩個孩子,list[i]<list[i+1]:默認左孩子大于右孩子*/{i++; /*左孩子小于右孩子直接i++ ,list[i]為右孩子值*/}if (temp >= list[i]) /*節點大于等于(左/右)孩子直接退出不替換節點值*/{break;}list[NodeIndex] = list[i]; /*替換節點和(左/右)孩子之間的值,保持結點大于左右孩子*/NodeIndex = i; /*重新設置結點值,循環查詢*/}list[NodeIndex] = temp; /*替換(左/右)孩子和結點之間的值*/ }歸并排序(Merge sort)
排序思想:“歸并”一詞的中文含義就是合并、并入的意思,而在數據結構中的定義是將兩個或兩個以上的有序表組合成一個新的有序表。
歸并排序(Merging Sort)就是利用歸并的思想實現的排序方法。它的原理是假設初始序列含有n個記錄,則可以看成是n個有序的子序列,每個子序列的長度為1,然后兩兩歸并,得到?n/2?(?x?表示不小于x的最小整數)個長度為2或1的有序子序列;再兩兩歸并,……,如此重復,直至得到一個長度為n的有序序列為止,這種排序方法稱為2路歸并排序。
復雜度:O(nlogn)?。
穩定性:穩定。
代碼實例:
static void Main(string[] args) {int[] list = { 50, 10, 90, 30, 70, 40, 20 };MeSort(list, 0, list.Length - 1);Console.WriteLine("歸并排序的結果:{0}", string.Join(",", list)); }static void MeSort(int[] list, int start, int end) {if (start < end){int middle = (start + end) / 2; /*對數組進行分組*/MeSort(list, start, middle); /*分組左序列*/MeSort(list, middle + 1, end); /*分組右序列*/MergeS(list, start, middle, end); /*對左右序列進行合并(歸并)*/} }static void MergeS(int[] list, int first, int middle, int end) {int IndexA = first; /*左序列起始位置*/int IndexB = middle + 1; /*右序列起始位置*/int[] tempList = new int[end - first + 1]; /*左右序列合并后的臨時數組*/int tempIndex = 0;while (IndexA <= middle && IndexB <= end) /*循環左右序列中的數據*/{if (list[IndexA] >= list[IndexB]) /*對比左右序列中數據大小*/{tempList[tempIndex++] = list[IndexB++]; /*右元素大于左元素,把右元素存放到臨時數組tempList中,并把臨時數組tempIndex++,然后在取右序列中下一元素*/}else{tempList[tempIndex++] = list[IndexA++]; /*左元素大于右元素,把左元素存放到臨時數組tempList中,并把臨時數組tempIndex++,然后在取在序列中下一元素*/}}while (IndexA <= middle) /*有一側子表遍歷完后,跳出循環,將另外一側子表剩下的數一次放入暫存數組中*/{tempList[tempIndex++] = list[IndexA++];}while (IndexB <= end){tempList[tempIndex++] = list[IndexB++];}tempIndex = 0; /*設置臨時數組從第1位開始替換*/for (int i = first; i <= end; i++) /*臨時數組替換List數組中數據*/{list[i] = tempList[tempIndex++];} }快速排序(quick sort)
排序思想:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
復雜度:O(nlogn)?。
穩定性:不穩定。
?
代碼實例:
static void Main(string[] args) { int[] list = { 50, 10, 90, 30, 70, 40, 20 }; QuickSort(list, 0, list.Length - 1); Console.WriteLine("快速排序的結果:{0}", string.Join(",", list)); } private static void QuickSort(int[] list, int start, int end) { int pivot; if (start < end) { pivot = Partition(list, start, end); /* 對序列一分為二數出中間值 */QuickSort(list, start, pivot - 1); /* 對低端序列進行排序 */ QuickSort(list, pivot + 1, end); /* 對高端序列進行排序 */ } } private static int Partition(int[] list, int first, int end) { int pivotkey = list[first]; /* 默認取序列中第0位為樞軸 */ while (first < end) { while (first < end && list[end] >= pivotkey) /*比樞軸小的記錄交換到低端*/ { end--; } swap(list, first, end); while (first < end && list[first] <= pivotkey) /*比樞軸大的記錄交換到高端*/ { first++; } swap(list, first, end); } return first; /*返回樞軸值*/ } /// <summary> /// 替換數組A于B之間的位置 /// </summary> private static void swap(int[] list, int A, int B) { int temp = list[A]; list[A] = list[B]; list[B] = temp; }?
常見排序方法基本就這些。已分享完畢.....
排序性能和速度快速排序優于其他常見排序方法。
?
轉載于:https://www.cnblogs.com/caokai520/p/4359425.html
總結
以上是生活随笔為你收集整理的C# 数据结构--排序[下]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MFC socket网络编程(流程示例)
- 下一篇: C#中的多线程 - 并行编程 z