當前位置:
首頁 >
Visual C# 诠释常用排序算法
發布時間:2025/3/15
43
豆豆
生活随笔
收集整理的這篇文章主要介紹了
Visual C# 诠释常用排序算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Visual C# 詮釋常用排序算法
前段時間因為項目需要,做了個用來對數組排序的類,順便把以前學過的幾種排序算法用C#實現一下。用C#的一些機制來詮釋了一下算法的是實現。在閱讀本之前,需要一些對C#的有些基本的了解,了解方法參數中out ,ref的作用,掌握面向對象的一些基本思想。1. 插入排序
1.1. 基本思想:
每次將一個待排序的數據元素,插入到前面已經排好序的數列中的適當位置,使數列依然有序;直到待排序數據元素全部插入完為止。
1.2. 排序過程:
【示例】:
[初始關鍵字]
?????? [49] 38 65 97 76 13 27 49
(38) [38 49] 65 97 76 13 27 49
(65) [38 49 65] 97 76 13 27 49
(97) [38 49 65 97] 76 13 27 49
(76) [38 49 65 76 97] 13 27 49
(13) [13 38 49 65 76 97] 27 49
(27) [13 27 38 49 65 76 97] 49
(49) [13 27 38 49 49 65 76 97]
1.3. 程序實現
<summary>
///?插入排序算法
///?</summary>
///?<param?name="dblArray"></param>
static?void?InsertSort(ref?double[]?dblArray)
{
for(int?i?=?1?;?i?<?dblArray.Length?;?i++)
{
int?frontArrayIndex?=?i-1?;
int?CurrentChangeIndex?=?i?;
while(frontArrayIndex>=0)
{
if(dblArray[CurrentChangeIndex]?<?dblArray[frontArrayIndex])
{
ChangeValue(ref?dblArray[CurrentChangeIndex],ref?dblArray[frontArrayIndex]);
CurrentChangeIndex?=?frontArrayIndex?;
}
frontArrayIndex--;
}
}
}
///?<summary>
///?在內存中交換兩個數字的值
///?</summary>
///?<param?name="A"></param>
///?<param?name="B"></param>
static?void?ChangeValue?(ref?double?A?,ref?double?B)
{
double?Temp?=?A?;
A?=?B?;
B?=?Temp?;
}
2. 選擇排序
2.1. 基本思想:
每一趟從待排序的數據元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最后,直到全部待排序的數據元素排完。
2.2. 排序過程:
【示例】:
初始關鍵字?????????? [49 38 65 97 76 13 27 49]
第一趟排序后 13 [38 65 97 76 49 27 49]
第二趟排序后 13 27 [65 97 76 49 38 49]
第三趟排序后 13 27 38 [97 76 49 65 49]
第四趟排序后 13 27 38 49 [49 97 65 76]
第五趟排序后 13 27 38 49 49 [97 97 76]
第六趟排序后 13 27 38 49 49 76 [76 97]
第七趟排序后 13 27 38 49 49 76 76 [ 97]
最后排序結果 13 27 38 49 49 76 76 97
2.3. 程序實現
///?<summary>
///?選擇排序?
///?</summary>
///?<param?name="dblArray"></param>
private?static?void?SelectSort(ref?double[]?dblArray)
{
for(int?i?=0?;?i<?dblArray.Length;?i++)
{
double?MinValue?=?dblArray[i]?;
int?MinValueIndex?=?i?;
for(int?j?=?i;?j<?dblArray.Length;?j++)
{
if(MinValue?>?dblArray[j]?)
{
MinValue?=?dblArray[j]?;
MinValueIndex?=?j?;
}
}
ExChangeValue(ref?dblArray[i],?ref?dblArray[MinValueIndex]);
}
}
///?<summary>
///?交換數據
///?</summary>
///?<param?name="A"></param>
///?<param?name="B"></param>
private?static?void?ExChangeValue(ref?double?A?,?ref?double?B)
{
double?Temp?=?A?;
A?=?B?;
B?=?Temp?;
}
3. 冒泡排序
3.1. 基本思想:
兩兩比較待排序數據元素的大小,發現兩個數據元素的次序相反時即進行交換,直到沒有反序的數據元素為止。
3.2. 排序過程:
設想被排序的數組R[1..N]垂直豎立,將每個數據元素看作有重量的氣泡,根據輕氣泡不能在重氣泡之下的原則,從下往上掃描數組R,凡掃描到違反本原則的輕氣泡,就使其向上"漂浮",如此反復進行,直至最后任何兩個氣泡都是輕者在上,重者在下為止
【示例】:
49 13 13 13 13 13 13 13
38 49 27 27 27 27 27 27
65 38 49 38 38 38 38 38
97 65 38 49 49 49 49 49
76 97 65 49 49 49 49 49
13 76 97 65 65 65 65 65
27 27 76 97 76 76 76 76
49 49 49 76 97 97 97 97
3.3. 程序實現
程序支持順序和倒序排列。
///?<summary>
///?冒泡算法
///?</summary>
///?<param?name="abarray"></param>
///?<param?name="IsAscending">是否順序排序</param>
///?<returns></returns>
private?static?double[]?BubbleArithmetic(double[]?abarray?,bool?IsAscending)
{
if(abarray.Length?>?0?)
{
for(int?i?=?abarray.Length-1?;i?>=0?;i--)
{
for(int?j?=?i-1?;?j>=0?;?j--)
{
if(CheckAccordCondition(abarray[i],abarray[j],IsAscending))
{
ExChangeValue(ref?abarray[i],ref?abarray[j]);
}
}
}
}
return?abarray;
}
///?<summary>
///?交換數據
///?</summary>
///?<param?name="A"></param>
///?<param?name="B"></param>
private?static?void?ExChangeValue(ref?double?A?,?ref?double?B)
{
double?Temp?=?A?;
A?=?B?;
B?=?Temp?;
}
///?<summary>
///?是否符合條件
///?</summary>
///?<returns></returns>
private?static?bool?CheckAccordCondition(double?data1?,double?data2,?bool?IsAscending)
{
if(data1?>?data2)
{
return?IsAscending?==?true???true?:false;
}
else
{
return?IsAscending?==?true???false?:true?;
}
}
4. 快速排序
4.1. 基本思想:
在當前無序區R[1..H]中任取一個數據元素作為比較的"基準"(不妨記為X),用此基準將當前無序區劃分為左右兩個較小的無序區:R[1..I-1]和R[I+1..H],且左邊的無序子區中數據元素均小于等于基準元素,右邊的無序子區中數據元素均大于等于基準元素,而基準X則位于最終排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),當R[1..I-1]和R[I+1..H]均非空時,分別對它們進行上述的劃分過程,直至所有無序子區中的數據元素均已排序為止。
4.2. 排序過程:
【示例】:
初始關鍵字 [49 38 65 97 76 13 27 49]
第一次交換后 [27 38 65 97 76 13 49 49]
第二次交換后 [27 38 49 97 76 13 65 49]
第三次交換后 [27 38 13 97 76 49 65 49]
第四次交換后 [27 38 13 49 76 97 65 49]
[27 38 13 49 76 97 65 49]
(一次劃分過程)
初始關鍵字 [49 38 65 97 76 13 27 49]
一趟排序之后 [27 38 13] 49 [76 97 65 49]
二趟排序之后 [13] 27 [38] 49 [49 65]76 [97]
三趟排序之后 13 27 38 49 49 [65]76 97
最后的排序結果 13 27 38 49 49 65 76 97
各趟排序之后的狀態
4.3. 程序實現
///?<summary>
///?快速排序法
///?</summary>
///?<param?name="dbArray"></param>
///?<param?name="StartIndex"></param>
///?<param?name="EndIndex"></param>
private?static?void?QuickSort(?ref?double[]?dbArray?,int?StartIndex?,int?EndIndex)
{
//基數
int?CurrentIndex?=?StartIndex?;
//順序查找
bool?IsOrderSearched?=?true?;
//反序查找
bool?IsDisOrderSearched?=?true?;
while(IsOrderSearched?||?IsDisOrderSearched)
{
IsDisOrderSearched?=?false?;
IsOrderSearched?=?false?;
for(int?i?=EndIndex?;?i>CurrentIndex?;i--)
{
if(dbArray[i]?<?dbArray[CurrentIndex])
{
ExChangeValue(ref?dbArray[i]?,ref?dbArray[CurrentIndex]);
CurrentIndex?=?i?;
IsDisOrderSearched?=?true?;
break?;
}
}
for(int?i?=?StartIndex?;?i?<?CurrentIndex?;?i++)
{
if(dbArray[i]?>?dbArray[CurrentIndex])
{
ExChangeValue(ref?dbArray[i]?,ref?dbArray[CurrentIndex]);
CurrentIndex?=?i?;
IsOrderSearched?=?true?;
break?;
}
}
}
if(?EndIndex?-?StartIndex?>?0?)
{
if(CurrentIndex?!=?StartIndex?)
{
QuickSort(ref?dbArray?,StartIndex,CurrentIndex?-1);
}
if(CurrentIndex?!=?EndIndex)
{
QuickSort(ref?dbArray?,CurrentIndex+1,EndIndex);
}
}
}
///?交換數據
///?</summary>
///?<param?name="A"></param>
///?<param?name="B"></param>
private?static?void?ExChangeValue(ref?double?A?,?ref?double?B)
{
double?Temp?=?A?;
A?=?B?;
B?=?Temp?;
}
5. 堆排序
5.1. 基本思想:
堆排序是一樹形選擇排序,在排序過程中,將R[1..N]看成是一顆完全二叉樹的順序存儲結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關系來選擇最小的元素。
5.2. 堆的定義:
N個元素的序列K1,K2,K3,...,Kn.稱為堆,當且僅當該序列滿足特性:Ki≤K2i Ki ≤K2i+1(1≤ I≤ [N/2])。
堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉子結點的關鍵字均大于等于其孩子結點的關鍵字。例如序列10,15,56,25,30,70就是一個堆,它對應的完全二叉樹如上圖所示。這種堆中根結點(稱為堆頂)的關鍵字最小,我們把它稱為小根堆。反之,若完全二叉樹中任一非葉子結點的關鍵字均大于等于其孩子的關鍵字,則稱之為大根堆。
5.3. 排序過程:
堆排序正是利用小根堆(或大根堆)來選取當前無序區中關鍵字小(或最大)的記錄實現排序的。我們不妨利用大根堆來排序。每一趟排序的基本操作是:將當前無序區調整為一個大根堆,選取關鍵字最大的堆頂記錄,將它和無序區中的最后一個記錄交換。這樣,正好和直接選擇排序相反,有序區是在原記錄區的尾部形成并逐步向前擴大到整個記錄區。
【示例】:對關鍵字序列42,13,91,23,24,16,05,88建堆。
| ? |
| ? |
5.4. 程序實現
///?<summary>
///?小根堆排序
///?</summary>
///?<param?name="dblArray"></param>
///?<param?name="StartIndex"></param>
///?<returns></returns>
private?static?void?HeapSort(ref?double[]?dblArray?)
{
for(int?i?=?dblArray.Length?-1?;?i?>=?0;?i--)
{?
if(2*i+1<dblArray.Length)
{
int?MinChildrenIndex?=?2*i+1?;
//比較左子樹和右子樹,記錄最小值的Index
if(2*i+2?<?dblArray.Length?)
{
if(dblArray[2*i+1]>dblArray[2*i+2])
MinChildrenIndex?=?2*i+2;
}
if(dblArray[i]?>?dblArray[MinChildrenIndex])
{
ExchageValue(ref?dblArray[i],ref?dblArray[MinChildrenIndex]);
NodeSort(ref?dblArray?,MinChildrenIndex);
}
}
}?
}
///?<summary>
///?節點排序
///?</summary>
///?<param?name="dblArray"></param>
///?<param?name="StartIndex"></param>
private?static?void?NodeSort(ref?double[]?dblArray,int?StartIndex)
{
while(2*StartIndex+1?<?dblArray.Length)
{
int?MinChildrenIndex?=?2*StartIndex+1?;
if(2*StartIndex+2?<?dblArray.Length?)
{?
if(dblArray[2*StartIndex+1]>dblArray[2*StartIndex+2])
{
MinChildrenIndex?=?2*StartIndex+2;
}
}
if(dblArray[StartIndex]?>?dblArray[MinChildrenIndex])
{
ExchageValue(ref?dblArray[StartIndex],ref?dblArray[MinChildrenIndex]);
StartIndex?=?MinChildrenIndex?;
}
}
}
///?<summary>
///?交換值
///?</summary>
///?<param?name="A"></param>
///?<param?name="B"></param>
private?static?void?ExchageValue(ref?double?A?,?ref?double?B)
{
double?Temp?=?A?;
A?=?B?;
B?=?Temp?;
}
總結:
人常說算法是程序的靈魂,在作項目的過程中時常注意且不可靈魂出竅。時常去回顧一下以前的數據重要性就如同基督徒每周要做禮拜一樣。不能因為有了C# 和Java這種平臺之后,就忽略了基礎的重要性。
轉載于:https://www.cnblogs.com/bluedy1229/articles/962977.html
總結
以上是生活随笔為你收集整理的Visual C# 诠释常用排序算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PDF N-Up Maker:一个把PD
- 下一篇: 如何关闭父窗体?C#