go語言十大排序演算法總結(下篇)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

希爾排序

希爾排序基本思想: 先取一個小於n的整數d1作為第一個增量,把檔案的全部記錄分成d1個組。所有距離為dl的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然後,取第二個增量d2《d1重複上述的分組和排序,直至所取的增量dt=1(dt《dt-l《…《d2《d1),即所有記錄放在同一組中進行直接插入排序為止。 該方法實質上是一種分組插入方法。
個人總結:

public class ShellSorter
{
public void Sort(int[] arr)
{
int inc;
for (inc = 1; inc <= arr.Length / 9; inc = 3 * inc + 1) ;
for (; inc > 0; inc /= 3)
{
for (int i = inc + 1; i <= arr.Length; i += inc)
{
int t = arr[i - 1];
int j = i;
while ((j > inc) && (arr[j - inc - 1] > t))
{
arr[j - 1] = arr[j - inc - 1];//交換資料
j -= inc;
}
arr[j - 1] = t;
}
}
}
}

歸併排序

設有兩個有序(升序)序列儲存在同一數組中相鄰的位置上,不妨設為A[l..m],A[m+1..h],將它們歸併為一個有序數列,並儲存在A[l..h]。

其時間複雜度無論是在最好情況下還是在最壞情況下均是O(nlog2n)。
///
/// 歸併排序之歸:歸併排序入口
/// ///無序的數組 /// 有序數組
/// Lihua(www.zivsoft.com)
int[] Sort(int[] data)
{
//取數組中間下標
int middle = data.Length / 2;
//初始化臨時數組let,right,並定義result作為最終有序數組
int[] left = new int[middle], right = new int[middle], result = new int[data.Length];
if (data.Length % 2 != 0)//若數組元素奇數個,重新初始化右臨時數組
{
right = new int[middle + 1];
}
if (data.Length <= 1)//只剩下1 or 0個元數,返回,不排序
{
return data;
}
int i = 0, j = 0;
foreach (int x in data)//開始排序
{
if (i < middle)//填充左數組
{
left[i] = x;
i++;
}
else//填充右數組
{
right[j] = x;
j++;
}
}
left = Sort(left);//遞迴左數組
right = Sort(right);//遞迴右數組
result = Merge(left, right);//開始排序
//this.Write(result);//輸出排序,測試用(lihua debug)
return result;
}
///
/// 歸併排序之並:排序在這一步
/// ///左數組 ///右數組 /// 合并左右數組排序後返回
int[] Merge(int[] a, int[] b)
{
//定義結果數組,用來儲存最終結果
int[] result = new int[a.Length + b.Length];
int i = 0, j = 0, k = 0;
while (i < a.Length && j < b.Length)
{
if (a[i] < b[j])//左數組中元素小於右數組中元素
{
result[k++] = a[i++];//將小的那個放到結果數組
}
else//左數組中元素大於右數組中元素
{
result[k++] = b[j++];//將小的那個放到結果數組
}
}
while (i < a.Length)//這裡其實是還有左元素,但沒有右元素
{
result[k++] = a[i++];
}
while (j < b.Length)//右右元素,無左元素
{
result[k++] = b[j++];
}
return result;//返回結果數組
}
註:此演算法由周利華提供(http://www.cnblogs.com/architect/archive/2009/05/06/1450489.html

基數排序

基數排序法又稱“桶子法”(bucket sort)或bin sort,顧名思義,它是透過索引值的部份資訊,將要排序的元素分配至某些“桶”中,藉以達到排序的作用,基數排序法是屬於穩定性的排序,其時間複雜度為O (nlog(r)m),其中r為所採取的基數,而m為堆數,在某些時候,基數排序法的效率高於其它的比較性排序法。
//基數排序
public int[] RadixSort(int[] ArrayToSort, int digit)
{
//low to high digit
for (int k = 1; k <= digit; k++)
{
//temp array to store the sort result inside digit
int[] tmpArray = new int[ArrayToSort.Length];
//temp array for countingsort
int[] tmpCountingSortArray = new int[10]{0,0,0,0,0,0,0,0,0,0};
//CountingSort
for (int i = 0; i < ArrayToSort.Length; i++)
{
//split the specified digit from the element
int tmpSplitDigit = ArrayToSort[i]/(int)Math.Pow(10,k-1) - (ArrayToSort[i]/(int)Math.Pow(10,k))*10;
tmpCountingSortArray[tmpSplitDigit] += 1;
}
for (int m = 1; m < 10; m++)
{
tmpCountingSortArray[m] += tmpCountingSortArray[m - 1];
}
//output the value to result
for (int n = ArrayToSort.Length - 1; n >= 0; n–)
{
int tmpSplitDigit = ArrayToSort[n] / (int)Math.Pow(10,k – 1) – (ArrayToSort[n]/(int)Math.Pow(10,k)) * 10;
tmpArray[tmpCountingSortArray[tmpSplitDigit]-1] = ArrayToSort[n];
tmpCountingSortArray[tmpSplitDigit] -= 1;
}
//copy the digit-inside sort result to source array
for (int p = 0; p < ArrayToSort.Length; p++)
{
ArrayToSort[p] = tmpArray[p];
}
}
return ArrayToSort;
}

計數排序

數排序, 基數排序, 桶排序等非比較排序演算法,平均時間複雜度都是O(n). 這些排序因為其待排序元素本身就含有了定位特徵,因而不需要比較就可以確定其前後位置,從而可以突破比較排序演算法時間複雜度O(nlgn)的理論下限.
計數排序是最簡單的特例,它要 求待排序元素是位於0到k之間的正整數 , 因而它是很特殊的情況,基本上沒有特別的應用價值; 但是另一方面, 它又是基數排序的基礎,或者說是一部分,所以簡單的描述一下:
輸入數組 A : 元素特徵是 0-k的正整數,可以有重複值;
輸出數組 B : 輸出A的一個非減序列
中間數組 C : 大小是k, 它的i( 0<= i <= k)索引位置儲存的是A元素集合中值是k的元素的個數有關.
演算法的基本思想是:
統計A中元素的值的集合, 以A中元素的值為索引, 將值的個數填寫到中間數組C的對應處.
對C從頭開始自累加, 這樣C中儲存的就是, 當輸入數組A中的值為當前索引時, 它前面的元素數量(包含重複元素).
將C依次輸出到輸出數組B中.
///
/// counting sort
/// ///input array ///the value arrange in input array ///
public int[] CountingSort(int[] arrayA, int arrange)
{
//array to store the sorted result,
//size is the same with input array.
int[] arrayResult = new int[arrayA.Length];
//array to store the direct value in sorting process
//include index 0;
//size is arrange+1;
int[] arrayTemp = new int[arrange+1];
//clear up the temp array
for(int i = 0; i <= arrange; i++)
{
arrayTemp[i] = 0;
}
//now temp array stores the count of value equal
for(int j = 0; j < arrayA.Length; j++)
{
arrayTemp[arrayA[j]] += 1;
}
//now temp array stores the count of value lower and equal
for(int k = 1; k <= arrange; k++)
{
arrayTemp[k] += arrayTemp[k - 1];
}
//output the value to result
for (int m = arrayA.Length-1; m >= 0; m–)
{
arrayResult[arrayTemp[arrayA[m]] – 1] = arrayA[m];
arrayTemp[arrayA[m]] -= 1;
}
return arrayResult;
}

根堆排序

堆排序是一種樹形選擇排序,在排序過程中,將A[n]看成是完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係來選擇最小的元素。

堆排序是不穩定的。演算法時間複雜度O(nlog n)。
///
/// 小根堆排序
/// /// /// ///

private 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);
}
}
}
}
///
/// 節點排序
/// /// /// private 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;
}
}
}

///
/// 交換值
/// /// /// private void ExchageValue(ref double A, ref double B)
{
double Temp = A;
A = B;
B = Temp;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.