亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

【算法日積月累】1-選擇排序

neuSnail / 2643人閱讀

摘要:選擇排序算法實現(xiàn)實現(xiàn)選擇排序,記錄最小元素的索引,最后才交換位置說明交換兩個數(shù)組中的元素,在中有更簡單的寫法,這是的語法糖,其它語言中是沒有的。和語言中比較器的實現(xiàn)前面我們說到了,我們?yōu)榱送怀雠判蛩惴ǖ乃枷?,將所有的例子僅限在數(shù)組排序中。

“算法”的入門,從“排序算法”開始,希望通過“排序算法”這一部分的學(xué)習(xí),能夠讓我們認識到“算法”的威力,“算法”不僅僅只存在與我們的面試中(那時只是因為我不知道“算法”而已),“算法”無處不在,“算法”很有用。

下面是一些說明:

1、會直接使用“空間復(fù)雜度”和“時間復(fù)雜度”的概念,不妨先有個印象,實在糾結(jié)的話,可以去翻翻書,“空間復(fù)雜度”和“時間復(fù)雜度”最多的應(yīng)用就在于比較不同算法的優(yōu)劣;

2、“排序算法”這一章節(jié)為了方便說明,使用的例子都是以“整數(shù)數(shù)組”為例,并且是“升序排序”,學(xué)習(xí)過 Java 語言的朋友就知道,待排序的也可以是對象,只要實現(xiàn)了相關(guān)的接口,實現(xiàn)了相應(yīng)的比較規(guī)則,就可以進行排序。

我們選擇“選擇排序”作為算法入門的開篇。理由如下:

1、“選擇排序”算法的思想十分簡單,非常接近我們的思維方式:先找最小的數(shù)、再找第 2 小的數(shù),依次類推,最后剩下的就是數(shù)組中最大的元素;

2、“選擇排序”的實現(xiàn)也很簡單。

一、通過具體例子理解“選擇排序”的思想

思想:不斷地選擇剩余元素之中的最小者。

“選擇排序”算法的特點

1、每一輪交換都能排定一個元素,交換的總次數(shù)是固定的;

說明:“交換的總次數(shù)”等于“元素的總數(shù) - 1”,因此算法的時間復(fù)雜度取決于比較的次數(shù);

2、運行時間和輸入無關(guān),即:一個“已經(jīng)有序”的數(shù)組、一個所有的元素都相等的數(shù)組、一個元素隨機排列的數(shù)組所用的排序時間是一樣的;

說明:后續(xù)我們會編寫一些測試用例,比較不同的算法在不同的測試用例上的運行時間。這些測試用例中,就有以下 $3$ 種。

(1)一個“已經(jīng)有序”的數(shù)組:例如:[4, 5, 6, 8, 9, 10],以后我們學(xué)習(xí)的排序算法中,就有一種算法名叫“插入排序”就能檢測出數(shù)組是不是有序的,極端情況下,“插入排序”算法看一遍數(shù)組中的元素,就知道數(shù)組已經(jīng)有序了,后續(xù)就什么都不用做了。而“選擇排序”得一遍又一遍看數(shù)組的元素好幾遍,“幾乎是”有多少個數(shù),就會看數(shù)組多少遍,每一遍選出當前沒有排定元素中的最小者;

(2)一個所有的元素都相等的數(shù)組,例如:[6, 6, 6, 6, 6, 6]

(3)一個元素隨機排列的數(shù)組,就是我們一般意義下,雜亂無序的數(shù)組,例如:[8, 18, 10, 6, 5, 4, 20]。

3、數(shù)據(jù)移動是最少的。

這點應(yīng)該說是“選擇排序”的優(yōu)點了,如果我們的排序任務(wù)對交換操作非常敏感,不妨考慮“選擇排序”。

例如:我們待排序的是碼頭上的集裝箱,交換集裝箱的成本是很高的,此時“選擇排序”就是最好的選擇。

小貼士:這一部分內(nèi)容不需要記住,等到后面接觸了“插入排序”、“歸并排序”、“快速排序”等其它排序算法以后,再與“選擇排序”進行比較,就不難理解了。

“選擇排序”算法實現(xiàn)

Python 實現(xiàn)1:

def swap(nums, idx1, idx2):
    if idx1 == idx2:
        return
    temp = nums[idx1]
    nums[idx1] = nums[idx2]
    nums[idx2] = temp


def select_sort(nums):
    """
    選擇排序,記錄最小元素的索引,最后才交換位置
    :param nums:
    :return:
    """
    l = len(nums)
    for i in range(l):
        min_index = i
        for j in range(i + 1, l):
            if nums[j] < nums[min_index]:
                min_index = j
        swap(nums, i, min_index)

說明:交換兩個數(shù)組中的元素,在 Python 中有更簡單的寫法,這是 Python 的語法糖,其它語言中是沒有的。

Python 實現(xiàn)2:主體部分和“Python 實現(xiàn)1”是一樣的。

def select_sort(nums):
    """
    選擇排序,記錄最小元素的索引,最后才交換位置
    :param nums:
    :return:
    """
    l = len(nums)
    for i in range(l):
        min_index = i
        for j in range(i + 1, l):
            if nums[j] < nums[min_index]:
                min_index = j
        nums[i], nums[min_index] = nums[min_index], nums[i]

這就是“選擇排序”算法。

如果你看到自己編寫的程序不正確,可以在程序中增加打印輸出,幫助你調(diào)試程序:

二、時間復(fù)雜度與空間復(fù)雜度 時間復(fù)雜度:O(n^2)

分析:第 1 輪要看 n 個元素;

第 2 輪要看 n-1 個元素;

第 3 輪要看 n-2 個元素;

……

第 n 輪要看 1 個元素;

對它們求和,用等差數(shù)列的通項公式。不過其實你也不用計算它,“時間復(fù)雜度”的計算我們只看次數(shù)最高的,所以“選擇排序”是平方時間復(fù)雜度。

空間復(fù)雜度:O(1)

分析:我們在交換兩個數(shù)組元素位置的時候,使用了 1 個輔助的空間。

三、熱身練習(xí)

是不是覺得很簡單,后面難度會一點一點加上來。此時,我們不妨做一些熱身的練習(xí),我們后面會用到。這些練習(xí)只是減輕一點我們后面編寫測試用例的工作量,自己設(shè)計函數(shù)參數(shù)就好。

練習(xí)1:編寫三個函數(shù),分別生成上文中提到的 3? 種類型的數(shù)組,要求能夠自定義生成數(shù)組的大小,這樣我們以后編寫測試用例的時候,就可以使用這些函數(shù)了。

練習(xí)2:編寫一個函數(shù),判斷一個數(shù)組是否是升序排序。這個函數(shù)用于判斷我們的算法是否正確。

四、補充知識

以下補充的知識是針對零基礎(chǔ)的朋友們的,因為我也是零基礎(chǔ)過來的,覺得這些東西可以說一下。

1、交換兩個變量的值

交換兩個變量的值,在排序中是常見的操作,并且也是程式化的,特別好記。先給出 Java 的寫法,再給出 Python 的寫法,最后給出“不是人的寫法”。

Java 寫法:

int temp = a;
a = b;
b = temp;

說明:這段代碼其實很好理解,要交換兩個變量的值,給要讓變量 a 把位置讓出來,即 int temp = a,然后把另一個變量 b 的值復(fù)制給 a,即 a = b,最后把之前 a 放在 temp 里的值賦給 b。這么說比較拗口,但其實我每次寫這段代碼的時候,都不用想這個過程的。因為這段代碼有規(guī)律可循:首先引入一個輔助變量 temp,這是必要的,然后就開始“首尾相接”了,你們看一下,是不是這個特點,最后接回 temp,記住這個規(guī)律就可以了。在 Python 中是這樣寫的:

Python 寫法1:

temp = a
a = b
b = temp

不過,Python 是一門神奇的編程語言,它提供了語法糖。

使用 Python 語法糖交換兩個變量的值
a, b = b, a

就可以交換兩個變量的值,不妨動手驗證一下:

是不是很酷,Python 的寫法有的時候更像偽代碼,更符合人的思維,但我沒有說 Python 更好的意思。其實 Python 解釋器在后臺也是引入了輔助變量完成兩個變量的交換。其實,交換兩個變量的值,有更高效的做法,下面給出兩個交換變量的代碼,這兩種方法都不用引入輔助變量,相信聰明的你一定不難理解。

基于加減法交換兩個變量的值

基于異或運算交換兩個變量的值

這里利用到了異或運算的特點:異或運算可以理解成不進位的加法。那么一個數(shù)兩次異或同一個數(shù),就和原來的數(shù)相等。上面基于異或運算交換兩個變量的值就利用這個性質(zhì)。如果你還不熟悉異或運算,不妨查閱一些資料。

2、Java 和 Python 語言中比較器的實現(xiàn)

前面我們說到了,我們?yōu)榱送怀雠判蛩惴ǖ乃枷?,將所有的例子僅限在數(shù)組排序中。事實上 Java 和 Python 這些面向?qū)ο蟮木幊陶Z言都支持對象的排序,只要給它們定義相應(yīng)的比較規(guī)則即可。有兩種方式,Python 和 Java 都是支持的:

(1)為對象添加用于比較的函數(shù)

在 Python 中,有一個魔法函數(shù),實現(xiàn)它即可:

def __cmp__(self, other):
    pass

定義這個魔法函數(shù),就可以使用對象集合進行排序了。

在 Java 中,實現(xiàn) Comparable 接口中的 compareTo 方法。

如果你覺得給對象添加用于比較的函數(shù),這種做法的侵入性比較強(因為修改了類),那么你可以在排序的方法中,傳入比較規(guī)則。

(2)在排序的方法中,傳入比較規(guī)則

在 Python 中,比較規(guī)則可以通過 lambda 表達式傳入:

在 Java 中,可以傳入一個實現(xiàn)了 Comparator 接口的對象。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/45037.html

相關(guān)文章

  • 學(xué)Python說簡單真的簡單,說難也難,就由過來人給你總結(jié)為什么吧。

    摘要:數(shù)據(jù)科學(xué)其實就是機器學(xué)習(xí),數(shù)據(jù)分析和數(shù)據(jù)可視化。機器學(xué)習(xí)通過實現(xiàn)算法,該算法能夠自動檢測輸入中的模式。一般應(yīng)用于人臉識別語音識別熱門機器學(xué)習(xí)算法包括神經(jīng)網(wǎng)絡(luò)深度學(xué)習(xí)支持向量機隨機森林進行數(shù)據(jù)分析可視化進行數(shù)據(jù)可視化時,是非常熱門的庫。 ...

    HtmlCssJs 評論0 收藏0
  • 算法日積月累】0-寫在前面的話

    摘要:現(xiàn)在發(fā)出來的版本,我重新使用了語言實現(xiàn)。其實我之前介紹的老師課程也大量參考和使用算法這本書上的思路和例題??催@本書主要是讓我覺得算法可以以比較輕松的方式入門。劍指這本書主要用于準備算法面試,在網(wǎng)絡(luò)上備受好評。 我是一個半路出家的程序員,在我剛開始從事編碼工作的頭幾年,我沒有接觸過算法和數(shù)據(jù)結(jié)構(gòu),覺得它們是只會在我找工作的時候用得到的知識。盡管有很多人跟我說過算法和數(shù)據(jù)結(jié)構(gòu)無比重要,我也...

    flybywind 評論0 收藏0
  • 是,入坑小記

    摘要:種一顆樹最好的時機是十年前,其次是現(xiàn)在經(jīng)過一段刻骨的升本歷程,來到了西華大學(xué)。計劃是前進的路線圖免除對于以后學(xué)習(xí)的各自夸大的計劃,從實際出發(fā)找到適合自己的前進的路線圖。今年我歲,年輕。 種一顆樹最好的時機是十年前,其次是現(xiàn)在 經(jīng)過一段刻骨的升本歷程,來到了西華大學(xué)。明顯能感覺到自己又有了新的...

    CoXie 評論0 收藏0
  • 趁著課余時間學(xué)點Python(十四)文件操作

    摘要:我是布小禪,一枚自學(xué)萌新,跟著我每天進步一點點吧說了這么多暫時也就夠了,那么就告辭吧 文章目錄 ?? 前言 ??? 作者簡介 ??文件操作?1??、open函數(shù)...

    abson 評論0 收藏0
  • 聽說看了這份Java學(xué)習(xí)路線的同學(xué),畢業(yè)都拿到了大廠offer

    摘要:服務(wù)層這一層有點東西了,算是整個框架的核心,如果你跟敖丙一樣以后都是從事后端開發(fā)的話,我們基本上整個技術(shù)生涯,大部分時間都在跟這一層的技術(shù)棧打交道了,各種琳瑯滿目的中間件,計算機基礎(chǔ)知識,操作,算法數(shù)據(jù)結(jié)構(gòu),架構(gòu)框架,研發(fā)工具等等。 前言 自學(xué)/學(xué)習(xí)路線這樣的一期我想寫很久了,因為一直想寫的...

    Dean 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<