2011年6月4日 星期六

演算法 - 合併排序法 ( merge sort )

合併排序(Merge sort)(另譯:歸併排序)是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。

歸併操作的過程如下:

1.申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列
2.設定兩個指針,最初位置分別為兩個已經排序序列的起始位置
3.比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置
4.重複步驟3直到某一指針達到序列尾
5.將另一序列剩下的所有元素直接複製到合併序列尾


時間複雜度:O(n logn)
空間複雜度:O(n)

以上引用自維基百科:http://zh.wikipedia.org/wiki/%E5%90%88%E4%BD%B5%E6%8E%92%E5%BA%8F

以下利用 C# 程式碼示範:
public void sort(int n, int[] s)
{
    if (n > 1)
    {
        int left = n / 2, right = n - left;
        int[] l = new int[left];
        int[] r = new int[right];
        for (int i = 0; i < left; i++)
            l[i] = s[i];
        for (int i = 0; i < right; i++)
            r[i] = s[left + i];
        sort(left, l);
        sort(right, r);
        merge(left, right, l, r, s);
    }
}

void merge(int left, int right, int[] l, int[] r, int[] s)
{
    int i = 0, j = 0, k = 0;

    while (i < left && j < right)
    {
        if (l[i] < r[j])
        {
            s[k] = l[i];
            i++;
        }
        else
        {
            s[k] = r[j];
            j++;
        }
        k++;
    }
    if (i >= left)
        for (int m = j, c = 0; m < right; m ++, c ++)
            s[k + c] = r[m];
    else
        for (int m = i, c = 0; m < left; m ++, c ++)
            s[k + c] = l[m];
}
回首頁

演算法 - 選擇排序法 ( selection sort )

選擇排序(Selection sort)是一種簡單直觀的排序演算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列末尾。以此類推,直到所有元素均排序完畢。

時間複雜度:O(n2)
空間複雜度:O(1)

以上引用自維基百科:http://zh.wikipedia.org/wiki/%E9%81%B8%E6%93%87%E6%8E%92%E5%BA%8F

以下利用 C# 程式碼示範:
public void sort(int n, int[] s)
{
    int i, j, flag;
    for (i = 0; i < n - 1; i++)
    {
        flag = i;
        for (j = i + 1; j < n; j++)
            if (s[j] < s[flag])
                swap(ref s[j], ref s[flag]);
    }
}

void swap(ref int i, ref int j)
{
    int temp;
    temp = i;
    i = j;
    j = temp;
}
回首頁

演算法 - 插入排序法 ( insertion sort )

插入排序(Insertion Sort)的演算法描述是一種簡單直觀的排序演算法。它的工作原理是通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序在實現上,通常採用in-place排序(即只需用到O(1)的額外空間的排序),因而在從後向前掃描過程中,需要反覆把已排序元素逐步向後挪位,為最新元素提供插入空間。

時間複雜度:O(n2)
空間複雜度:O(1)

一般來說,插入排序都採用in-place在數組上實現。具體演算法描述如下:

1.從第一個元素開始,該元素可以認為已經被排序
2.取出下一個元素,在已經排序的元素序列中從後向前掃描
3.如果該元素(已排序)大於新元素,將該元素移到下一位置
4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置
5.將新元素插入到該位置中
6.重複步驟2

如果比較操作的代價比交換操作大的話,可以採用二分查找法來減少比較操作的數目。該演算法可以認為是插入排序的一個變種,稱為二分查找排序。


以上引用自維基百科:http://zh.wikipedia.org/wiki/%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F

以下利用 C# 程式碼示範:
public void sort(int n, int[] s)
{
    int i, j;
    int x;
    for (i = 1; i < n; i++)
    {
        x = s[i];
        j = i - 1;
        while (j >= 0 && s[j] > x)
        {
            s[j + 1] = s[j];
            j--;
        }
        s[j + 1] = x;
    }
}
回首頁