Visual C# 诠释常用排序算法
生活随笔
收集整理的這篇文章主要介紹了
Visual C# 诠释常用排序算法
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Visual C# 詮釋常用排序算法
前段時(shí)間因?yàn)轫?xiàng)目需要,做了個(gè)用來(lái)對(duì)數(shù)組排序的類(lèi),順便把以前學(xué)過(guò)的幾種排序算法用C#實(shí)現(xiàn)一下。用C#的一些機(jī)制來(lái)詮釋了一下算法的是實(shí)現(xiàn)。在閱讀本之前,需要一些對(duì)C#的有些基本的了解,了解方法參數(shù)中out ,ref的作用,掌握面向?qū)ο蟮囊恍┗舅枷搿?br />1. 插入排序
1.1. 基本思想:
每次將一個(gè)待排序的數(shù)據(jù)元素,插入到前面已經(jīng)排好序的數(shù)列中的適當(dāng)位置,使數(shù)列依然有序;直到待排序數(shù)據(jù)元素全部插入完為止。
1.2. 排序過(guò)程:
【示例】:
[初始關(guān)鍵字]
?????? [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. 程序?qū)崿F(xiàn)
<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>
///?在內(nèi)存中交換兩個(gè)數(shù)字的值
///?</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. 基本思想:
每一趟從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個(gè)元素,順序放在已排好序的數(shù)列的最后,直到全部待排序的數(shù)據(jù)元素排完。
2.2. 排序過(guò)程:
【示例】:
初始關(guān)鍵字?????????? [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]
最后排序結(jié)果 13 27 38 49 49 76 76 97
2.3. 程序?qū)崿F(xiàn)
///?<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>
///?交換數(shù)據(jù)
///?</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. 基本思想:
兩兩比較待排序數(shù)據(jù)元素的大小,發(fā)現(xiàn)兩個(gè)數(shù)據(jù)元素的次序相反時(shí)即進(jìn)行交換,直到?jīng)]有反序的數(shù)據(jù)元素為止。
3.2. 排序過(guò)程:
設(shè)想被排序的數(shù)組R[1..N]垂直豎立,將每個(gè)數(shù)據(jù)元素看作有重量的氣泡,根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R,凡掃描到違反本原則的輕氣泡,就使其向上"漂浮",如此反復(fù)進(jìn)行,直至最后任何兩個(gè)氣泡都是輕者在上,重者在下為止
【示例】:
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. 程序?qū)崿F(xiàn)
程序支持順序和倒序排列。
///?<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>
///?交換數(shù)據(jù)
///?</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. 基本思想:
在當(dāng)前無(wú)序區(qū)R[1..H]中任取一個(gè)數(shù)據(jù)元素作為比較的"基準(zhǔn)"(不妨記為X),用此基準(zhǔn)將當(dāng)前無(wú)序區(qū)劃分為左右兩個(gè)較小的無(wú)序區(qū):R[1..I-1]和R[I+1..H],且左邊的無(wú)序子區(qū)中數(shù)據(jù)元素均小于等于基準(zhǔn)元素,右邊的無(wú)序子區(qū)中數(shù)據(jù)元素均大于等于基準(zhǔn)元素,而基準(zhǔn)X則位于最終排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),當(dāng)R[1..I-1]和R[I+1..H]均非空時(shí),分別對(duì)它們進(jìn)行上述的劃分過(guò)程,直至所有無(wú)序子區(qū)中的數(shù)據(jù)元素均已排序?yàn)橹埂?br />
4.2. 排序過(guò)程:
【示例】:
初始關(guān)鍵字 [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]
(一次劃分過(guò)程)
初始關(guān)鍵字 [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
最后的排序結(jié)果 13 27 38 49 49 65 76 97
各趟排序之后的狀態(tài)
4.3. 程序?qū)崿F(xiàn)
///?<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)
{
//基數(shù)
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);
}
}
}
///?交換數(shù)據(jù)
///?</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. 基本思想:
堆排序是一樹(shù)形選擇排序,在排序過(guò)程中,將R[1..N]看成是一顆完全二叉樹(shù)的順序存儲(chǔ)結(jié)構(gòu),利用完全二叉樹(shù)中雙親結(jié)點(diǎn)和孩子結(jié)點(diǎn)之間的內(nèi)在關(guān)系來(lái)選擇最小的元素。
5.2. 堆的定義:
N個(gè)元素的序列K1,K2,K3,...,Kn.稱(chēng)為堆,當(dāng)且僅當(dāng)該序列滿(mǎn)足特性:Ki≤K2i Ki ≤K2i+1(1≤ I≤ [N/2])。
堆實(shí)質(zhì)上是滿(mǎn)足如下性質(zhì)的完全二叉樹(shù):樹(shù)中任一非葉子結(jié)點(diǎn)的關(guān)鍵字均大于等于其孩子結(jié)點(diǎn)的關(guān)鍵字。例如序列10,15,56,25,30,70就是一個(gè)堆,它對(duì)應(yīng)的完全二叉樹(shù)如上圖所示。這種堆中根結(jié)點(diǎn)(稱(chēng)為堆頂)的關(guān)鍵字最小,我們把它稱(chēng)為小根堆。反之,若完全二叉樹(shù)中任一非葉子結(jié)點(diǎn)的關(guān)鍵字均大于等于其孩子的關(guān)鍵字,則稱(chēng)之為大根堆。
5.3. 排序過(guò)程:
堆排序正是利用小根堆(或大根堆)來(lái)選取當(dāng)前無(wú)序區(qū)中關(guān)鍵字小(或最大)的記錄實(shí)現(xiàn)排序的。我們不妨利用大根堆來(lái)排序。每一趟排序的基本操作是:將當(dāng)前無(wú)序區(qū)調(diào)整為一個(gè)大根堆,選取關(guān)鍵字最大的堆頂記錄,將它和無(wú)序區(qū)中的最后一個(gè)記錄交換。這樣,正好和直接選擇排序相反,有序區(qū)是在原記錄區(qū)的尾部形成并逐步向前擴(kuò)大到整個(gè)記錄區(qū)。
【示例】:對(duì)關(guān)鍵字序列42,13,91,23,24,16,05,88建堆。
| ? |
| ? |
5.4. 程序?qū)崿F(xiàn)
///?<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?;
//比較左子樹(shù)和右子樹(shù),記錄最小值的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>
///?節(jié)點(diǎn)排序
///?</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?;
}
總結(jié):
人常說(shuō)算法是程序的靈魂,在作項(xiàng)目的過(guò)程中時(shí)常注意且不可靈魂出竅。時(shí)常去回顧一下以前的數(shù)據(jù)重要性就如同基督徒每周要做禮拜一樣。不能因?yàn)橛辛薈# 和Java這種平臺(tái)之后,就忽略了基礎(chǔ)的重要性。
轉(zhuǎn)載于:https://www.cnblogs.com/bluedy1229/articles/962977.html
總結(jié)
以上是生活随笔為你收集整理的Visual C# 诠释常用排序算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: PDF N-Up Maker:一个把PD
- 下一篇: 如何关闭父窗体?C#