選擇排序算法

眾所周知,最優(yōu)的排序算法的復(fù)雜度是O(nlogn),但在學(xué)習(xí)最優(yōu)算法前,我們先來看看O(n^2)復(fù)雜度的算法,由簡(jiǎn)入難。

算法描述:首先在未排序序列中找到最?。ù螅┰?,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續(xù)尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

選擇排序的代碼:

void selectionSort(int arr[], int n)
{
    
    for (int i = 0; i < n; i++)
    {
        int minIndex = i;
        for (int j = i+1; j < n; j++)
        {
            if (arr[j] < arr[minIndex])
            {
                minIndex = j;
            }
        }
        swap(arr[i] , arr[minIndex]);
    }
}

選擇排序的改進(jìn)

為了讓selectionSort()能接受不同類型(float,string ,char,或自定義類型)的數(shù)組,使用模板函數(shù)對(duì)其進(jìn)行改進(jìn):

template<typename T>
void selectionSort(T arr[], int n)
{
    
    for (int i = 0; i < n; i++)
    {
        int minIndex = i;
        for (int j = i+1; j < n; j++)
        {
            if (arr[j] < arr[minIndex])
            {
                minIndex = j;
            }
        }
        swap(arr[i] , arr[minIndex]);
    }
}

隨機(jī)生成數(shù)組

當(dāng)采用的數(shù)組個(gè)數(shù)較大時(shí),不可能一個(gè)一個(gè)的列舉出來,這里編寫一個(gè)隨機(jī)生成數(shù)組的程序,用來輔助數(shù)組的排序。此處建立一個(gè)命名空間SortTestHelper,用來放與排序測(cè)試相關(guān)的各種函數(shù),包括生產(chǎn)隨機(jī)數(shù)組generateRandomArray()、printArray()、testSort()、isSorted()等。
generateRandomArray()的實(shí)現(xiàn)

 //生成有n個(gè)元素的隨機(jī)數(shù)組,每個(gè)元素的隨機(jī)范圍為[rangeL,rangeR]
    int *generateRandomArray(int n, int rangeL, int rangeR)
    {
        assert(rangeL <= rangeR);//#include<cassert>
        int *arr = new int[n];
        srand(time(NULL));//#include<ctime>
        for (int i = 0; i < n; i++)
        {
            arr[i] = rand() % (rangeR - rangeL + 1) + rangeL;
        }
        return arr;
    }

測(cè)試代碼如下:

#include<iostream>
#include"SortTestHelper.h"
using namespace std;
template<typename T>
void selectionSort(T arr[], int n)
{
    
    for (int i = 0; i < n; i++)
    {
        int minIndex = i;
        for (int j = i+1; j < n; j++)
        {
            if (arr[j] < arr[minIndex])
            {
                minIndex = j;
            }
        }
        swap(arr[i] , arr[minIndex]);
    }
}
int main()
{
    int n = 1000;
    int *arr = SortTestHelper::generateRandomArray(n, 0, n);
    selectionSort(arr, n);
    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << ",";
    }
    cout << endl;
    delete[] arr;//注意要釋放掉內(nèi)存空間,否則發(fā)生內(nèi)存泄漏
    system("pause");
    return 0;
}

上述打印過程也可放在SortTestHelper()命名空間中:
printArray()

    void printArray(T arr[], int n)
    {
        for (int i = 0; i < n; i++)
        {
            cout << arr[i] << " ";
        }
        cout << endl;
    }

則測(cè)試代碼重新寫如下:

    int n = 1000;
    int *arr = SortTestHelper::generateRandomArray(n, 0, n);
    selectionSort(arr, n);
    SortTestHelper::printArray(arr, n);
    delete[] arr;

如何衡量一個(gè)排序算法的性能?

算法在某個(gè)數(shù)據(jù)集上的執(zhí)行時(shí)間可以衡量該算法的性能。接下來在SortTestHelper()空間中寫一個(gè)衡量算法性能的函數(shù)testSort()
testSort()

//測(cè)試算法性能,傳入的參數(shù)包括算法名稱、算法函數(shù)本身,測(cè)試用例及用例長(zhǎng)度
    template<typename T>
    void testSort(string sortName, void(*sort)(T[], int),T arr[],int n)
    {
        //clock_t表示時(shí)鐘周期的數(shù)據(jù)
        clock_t startTime = clock();
        sort(arr, n);
        clock_t endTime = clock();
        assert(isSorted(arr, n));
        //兩次時(shí)鐘周期差表示算法真正執(zhí)行的時(shí)鐘周期,CLOCKS_PER_SEC每秒時(shí)鐘周期個(gè)數(shù)
        cout << sortName << double(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
        return;
    }

如何衡量排序算法的正確性?

代碼如下:
isSorted()

//測(cè)試排序算法執(zhí)行的正確性
    template<typename T>
    bool isSorted(T arr[], int n)
    {
        for (int i = 0; i < n; i++)
        {
            if (arr[i] > arr[i + 1])
            {
                return false;
            }
            return true;
        }
    }

測(cè)試排序算法的性能

#include<iostream>
#include"SortTestHelper.h"
using namespace std;
template<typename T>
void selectionSort(T arr[], int n)
{
    
    for (int i = 0; i < n; i++)
    {
        int minIndex = i;
        for (int j = i+1; j < n; j++)
        {
            if (arr[j] < arr[minIndex])
            {
                minIndex = j;
            }
        }
        swap(arr[i] , arr[minIndex]);
    }
}
int main()
{
    int n = 10000;
    int *arr = SortTestHelper::generateRandomArray(n, 0, n);
    SortTestHelper::testSort("selectionSort:", selectionSort, arr, n);
    delete[] arr;
    system("pause");
    return 0;
}

整個(gè)SortTestHelper()空間的代碼如下:

#ifndef SELECTIONSORT_SORTTESTHELPER_H
#define SELECTIONSORT_SORTTESTHELPER_H
#include<iostream>
#include<string>
#include<ctime>
#include<cassert>
using namespace std;
namespace SortTestHelper
{
    //生成有n個(gè)元素的隨機(jī)數(shù)組,每個(gè)元素的隨機(jī)范圍為[rangeL,rangeR]
    int *generateRandomArray(int n, int rangeL, int rangeR)
    {
        assert(rangeL <= rangeR);//#include<cassert>
        int *arr = new int[n];
        srand(time(NULL));//#include<ctime>
        for (int i = 0; i < n; i++)
        {
            arr[i] = rand() % (rangeR - rangeL + 1) + rangeL;
        }
        return arr;
    }
    template<typename T>
    void printArray(T arr[], int n)
    {
        for (int i = 0; i < n; i++)
        {
            cout << arr[i] << " ,";
        }
        cout << endl;
        return;
    }
    //測(cè)試算法執(zhí)行的正確性
    template<typename T>
    bool isSorted(T arr[], int n)
    {
        for (int i = 0; i < n; i++)
        {
            if (arr[i] > arr[i + 1])
            {
                return false;
            }
            return true;
        }
    }
    //測(cè)試算法性能,傳入的參數(shù)包括算法名稱、算法函數(shù)本身,測(cè)試用例及用例長(zhǎng)度
    template<typename T>
    void testSort(string sortName, void(*sort)(T[], int),T arr[],int n)
    {
        //clock_t表示時(shí)鐘周期的數(shù)據(jù)
        clock_t startTime = clock();
        sort(arr, n);
        clock_t endTime = clock();
        assert(isSorted(arr, n));
        //兩次時(shí)鐘周期差表示算法真正執(zhí)行的時(shí)鐘周期,CLOCKS_PER_SEC每秒時(shí)鐘周期個(gè)數(shù)
        cout << sortName << double(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
        return;
    }
}
#endif  

說明:本文是在聽了波波老師的數(shù)據(jù)結(jié)構(gòu)算法課程后所做的筆記!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容