算法(第四版)讀書筆記--排序(1)API的定義以及選擇排序、插入排序

最近在看算法第四版,做一個讀書筆記,本文的所有實現基於C#

書中對排序的主要分類爲初級排序算法歸併排序、快速排序、優先隊列,本節主要介紹API以及選擇排序、插入排序。

一、API定義

利用面向對象編程的思想,我們可以定義一個類,僅向外部提供少量接口,複雜的內部實現由我們完整,使用時他人只需要知道每個結構的功用,不需要知道內部實現,並且以後優化也較爲方便。

排序算法的模板:


public class Sort_Templet
{
    /// <summary>
    /// 對引用類型的數據進行排序
    /// </summary>
    /// <typeparam name="T">數據類型</typeparam>
    /// <param name="a">數據</param>
    public virtual void sort<T>(T v)
    {
    }
    

    /// <summary>
    /// 對兩個數據進行比對,返回比對結果
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="v"></param>
    /// <param name="w"></param>
    /// <returns></returns>
    private static Boolean less<T>(T v, T w)
    {
        return true;
    }

    /// <summary>
    /// 交換
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="v"></param>
    /// <param name="w"></param>
    public static void exch<T>(List<T>v, int i, int j) where T : IComparable
    {
        T tem;
        tem = v[i];
        v[i] = v[j];
        v[j] = tem;
    }

    /// <summary>
    /// 顯示
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="v"></param>
    public static void Show<T>(T v)
    {
    }

    /// <summary>
    /// 驗證
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="v"></param>
    public static void isSorted<T>(T v)
    {

    }
}

模板代碼主要分爲幾個函數:

(1)排序函數sort():核心排序算法,對數據進行排序

(2)比較函數less():排序中採用的比較都來自於此,排序是需要比較的

(3)交換函數exch():大小比較之後一般需要交換

(4)顯示函數show():顯示結果

(5)驗證函數isSorted():驗證數據是否被正確排序

可以採用上述模板進行排序,首先選擇排序

二、選擇排序

排序中較爲常見的就是選擇排序,過程爲:首先,找到數組中最小的那個元素,其次,將其與數組的第一個元素交換位置,再次找到剩下元素中最小的那個與第二個元素交換位置,以此類推。

選擇排序與冒泡排序類似,區別在於比較之後的處理,選擇排序僅在一輪選擇結束之後纔會進行交換處理。增序排列代碼實現如下

public class Selection_Sort
{
    public static void Sort<T>(List<T> v) where  T: IComparable
    {
        int N =  v.Count;
        for (int i = 0; i < N; i++)
        {
            int j = i;
            int min = i;
            for (; j < N; j++)
            {
                if (v[i].CompareTo(v[j]) > 0)
                {
                    min = j;
                }
            }
            Sort_Templet.exch<T>(v,i, min);
        }

    }
}

選擇排序交換的次數總是N,比較的次數是N(N-1)/2~N^2,主要特點是運行時間和輸入數據無關,數據移動較少。

三、插入排序

通常人類整理撲克牌的方式是一張一張的來,每一張牌插入到其他已經有序的牌中的適當位置,在計算機的實現中,爲了給要插入的元素騰出空間,需要將其餘所有元素在插入之前向右移動一位,這種算法叫做插入排序。增序排列代碼實現如下:

public class Insert_Sort
{
    public static void Sort<T>(List<T> v) where T : IComparable
    {
        int N = v.Count;
        for (int i = 1; i < N; i++)
        {
            int j = i;
            for (; j > 0 && v[j].CompareTo(v[j-1]) < 0; j--)
            {
                Sort_Templet.exch<T>(v, j, j-1);
            }
        }

    }
}

最壞情況下需要N*N/2次比較和N*N/2次交換,最好情況下需要N-1次比較和0次交換,對於部分排序的數據性能較好

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章