排序算法大集合上

1. 插入排序

  1. 時(shí)間復(fù)雜度:最好是n-1屯阀,最壞是n(n-1)/2宪巨,平均為O(n^2)。
  2. 空間復(fù)雜度: O(1)
  3. 多作為快排的補(bǔ)充对竣,適用于少量的數(shù)據(jù)排序庇楞。
  4. 該算法是穩(wěn)定的,依賴初始排序順序柏肪。

過程:

  1. 以第一個(gè)數(shù)為已經(jīng)排好的隊(duì)列姐刁,將第二個(gè)數(shù)從隊(duì)列的右向左比較。
  2. 如果比它大烦味,那么聂使,該隊(duì)列里的元素就往右邊移動(dòng)一位壁拉,接著比較該元素左邊的元素;比它小柏靶,那么弃理,就把他存入該隊(duì)列里的元素的右邊一位。
  3. 形成一個(gè)新的隊(duì)列屎蜓,再走1痘昌,2。
    更多
# 插入排序
def insert(nums):
    for i in range(1, len(nums)):
        temp = nums[i]
        # 是否找到一個(gè)合適的位置插入
        label = False
        for j in range(i-1,-1,-1):
            # 找到位置了炬转,插入
            if nums[j] < temp:
                nums[j+1] = temp
                label = True
                break
            else:
                # 右移一位
                nums[j+1] = nums[j]
                
        if not label:
            nums[0] = temp

nums = [2,3,4,5,1,9,3,0,2,1]
insert(nums)
print(nums)

感覺上面這個(gè)方法有些復(fù)雜了辆苔,改進(jìn)了一下:

def insert(nums):
    for i in range(1, len(nums)):
        j = i
        while j > 0:
            if nums[j] < nums[j - 1]:
                nums[j], nums[j - 1] = nums[j - 1], nums[j]
                j -= 1
            else:
                break

2. 二分插入排序

  1. 時(shí)間復(fù)雜度:最好情況下:O(nlogn);最壞情況下:O(n^2)
    分析:最外層有n次循環(huán)扼劈;最內(nèi)側(cè)分為兩個(gè)部分驻啤,一個(gè)是二叉搜索(logn),一個(gè)是for循環(huán)(n)荐吵;所以骑冗,最好的情況是元素所在的位置就是插入位置(nlogn);最壞情況和平均的情況就是不斷在查找先煎,即為:n(logn+n)->n^2贼涩。
  2. 空間復(fù)雜度維O(1)。
  3. 是穩(wěn)定的薯蝎, 依賴初始排序順序遥倦。

過程:

  1. 在插入第i個(gè)元素時(shí),對(duì)前面的0~i-1元素進(jìn)行折半占锯,
  2. 先跟他們中間的那個(gè)元素比谊迄,如果小,則對(duì)前半再進(jìn)行折半烟央。
  3. 否則對(duì)后半進(jìn)行折半⊥嵩啵回歸2
  4. 直到left(左邊緣)>right(右邊緣)疑俭,再把第i個(gè)元素前1位與目標(biāo)位置之間的所有元素后移。
  5. 最后婿失,把第i個(gè)元素放在目標(biāo)位置上钞艇。
def insert_2_sort(nums):
    for i in range(1, len(nums)):
        left = 0
        right = i - 1
        key = nums[i]

        while left <= right:
            middle = (left+right)//2
            if key > nums[middle]:
                left = middle + 1
            else:
                right = middle - 1

        for j in range(i, left, -1):
            nums[j] = nums[j-1]

        nums[left] = key

a = [2,3,4,5,1,9,7,6,2,0,6]
insert_2_sort(a)

3. 希爾排序

  1. 空間復(fù)雜度為O(1)
  2. 時(shí)間復(fù)雜度則由增量(步長(zhǎng))而定。
    只要最終步長(zhǎng)為1任何步長(zhǎng)序列都可以工作豪硅。
    一個(gè)好的步長(zhǎng)序列評(píng)價(jià)時(shí)間復(fù)雜度可以達(dá)到O(n^1.5)
  3. shell排序是非穩(wěn)定排序
  4. 提高效率的思想:
    因?yàn)椴迦肱判虻臅r(shí)間復(fù)雜度依賴初始序列的順序哩照,所以通過大步長(zhǎng)的排序(時(shí)間復(fù)雜度低),使序列部分有序懒浮,這樣當(dāng)進(jìn)行小步長(zhǎng)排序時(shí)飘弧,時(shí)間復(fù)雜度也低识藤。

過程

  1. 把記錄按下標(biāo)的一定增量分組
  2. 對(duì)每組使用直接插入排序算法排序。
  3. 減小增量n次伶,若n > 0,進(jìn)入1痴昧;反之,算法終止
def shell(nums):
    gaps = 3
    for gap in range(1, gaps+1):
        for i in range(gap, len(nums)):
            key = nums[i]
            pointer = i - gap
            while key < nums[pointer] and pointer >= 0:
                nums[pointer+gap] = nums[pointer]
                pointer -= gap

            nums[pointer+gap] = key

4. 選擇排序

  1. 空間復(fù)雜度為O(1)
  2. 時(shí)間復(fù)雜度為O(n^2)
  3. 對(duì)比冒泡排序冠王,它少了很多的交換步驟赶撰。
  4. 不穩(wěn)定的排序方式

過程:

  1. 從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個(gè)元素柱彻。
  2. 存放在序列的起始位置豪娜,直到全部待排序的數(shù)據(jù)元素排完。
    類似冒泡排序哟楷。
def selection_sort(nums):
    for i in range(0, len(nums)):
        lowest = i
        for j in range(i, len(nums)):
            if nums[j] < nums[lowest]:
                lowest = j
        nums[lowest], nums[i] = nums[i], nums[lowest]

5. 冒泡排序

  1. 時(shí)間復(fù)雜度為O(n^2)
  2. 空間復(fù)雜度為O(1)
  3. 穩(wěn)定的排序方法
  4. 優(yōu)化:
    如果一個(gè)forloop沒有發(fā)生一次交換瘤载,說明已經(jīng)排好了,可以停止了后面的循環(huán)了吓蘑。
    在一次loop中記錄最后一次交換的位置惕虑,那么該位置后面數(shù)一定都是排好了的。所以這一部分就不用參與下面的比較了磨镶。

過程:

  1. 比較相鄰的元素溃蔫。如果第一個(gè)比第二個(gè)大,就交換他們兩個(gè)琳猫。
  2. 對(duì)每一對(duì)相鄰元素作同樣的工作伟叛,從開始第一對(duì)到結(jié)尾的最后一對(duì)。在這一點(diǎn)脐嫂,最后的元素應(yīng)該會(huì)是最大的數(shù)统刮。
  3. 針對(duì)所有的元素重復(fù)以上的步驟,除了最后一個(gè)账千。
  4. 持續(xù)每次對(duì)越來越少的元素重復(fù)上面的步驟侥蒙,直到?jīng)]有任何一對(duì)數(shù)字需要比較
    ------百度百科
def bubble_sort(nums):
    for i in range(1, len(nums)):
        for j in range(0, len(nums)-i):
            if nums[j+1] < nums[j]:
                nums[j+1], nums[j] = nums[j], nums[j+1]

a = [9,3,2,7,1,8,0,4,10,6]
bubble_sort(a)
print(a)

6. 雞尾酒排序/雙向冒泡排序

  1. 空間復(fù)雜度為:O(1)
  2. 平均和最差的時(shí)間復(fù)雜度為O(n^2),但如果序列在一開始已經(jīng)大部分排序過的話匀奏,趨近于O(n)鞭衩。
    原因:雙向排序可以避免大量小的數(shù)在最右邊而小數(shù)移動(dòng)緩慢的情況(升序)

過程:

  1. 傳統(tǒng)冒泡氣泡排序的雙向進(jìn)行,先讓氣泡排序由左向右進(jìn)行
  2. 再來讓氣泡排序由右往左進(jìn)行娃善,如此完成一次排序的動(dòng)作
  3. 使用left與right兩個(gè)旗標(biāo)來記錄左右兩端已排序的元素位置:
    當(dāng)left = right時(shí):結(jié)束
    否則:繼續(xù)1
def bubble_sort(nums):
    left = 1
    right = len(nums)
    while left < right:
        for i in range(0, len(nums)-left):
            if nums[i+1] < nums[i]:
                nums[i+1], nums[i] = nums[i], nums[i+1]
        left += 1
        for j in range(len(nums)-1, len(nums)-right, -1):
            if nums[j] < nums[j-1]:
                nums[j], nums[j-1] = nums[j-1], nums[j]
        right -= 1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末论衍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子聚磺,更是在濱河造成了極大的恐慌坯台,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘫寝,死亡現(xiàn)場(chǎng)離奇詭異蜒蕾,居然都是意外死亡稠炬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門滥搭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酸纲,“玉大人,你說我怎么就攤上這事瑟匆∶銎拢” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵愁溜,是天一觀的道長(zhǎng)疾嗅。 經(jīng)常有香客問我,道長(zhǎng)冕象,這世上最難降的妖魔是什么代承? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮渐扮,結(jié)果婚禮上论悴,老公的妹妹穿的比我還像新娘。我一直安慰自己墓律,他們只是感情好膀估,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耻讽,像睡著了一般察纯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上针肥,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天饼记,我揣著相機(jī)與錄音,去河邊找鬼慰枕。 笑死具则,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的具帮。 我是一名探鬼主播乡洼,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼匕坯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拔稳,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤葛峻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后巴比,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體术奖,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡礁遵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了采记。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佣耐。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖唧龄,靈堂內(nèi)的尸體忽然破棺而出兼砖,到底是詐尸還是另有隱情,我是刑警寧澤既棺,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布讽挟,位于F島的核電站,受9級(jí)特大地震影響丸冕,放射性物質(zhì)發(fā)生泄漏耽梅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一胖烛、第九天 我趴在偏房一處隱蔽的房頂上張望眼姐。 院中可真熱鬧,春花似錦佩番、人聲如沸众旗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)逝钥。三九已至,卻和暖如春拱镐,著一層夾襖步出監(jiān)牢的瞬間艘款,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工沃琅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哗咆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓益眉,卻偏偏與公主長(zhǎng)得像晌柬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子郭脂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 概述:排序有內(nèi)部排序和外部排序年碘,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大展鸡,一次不能容納全部...
    每天刷兩次牙閱讀 3,732評(píng)論 0 15
  • 概述 排序有內(nèi)部排序和外部排序屿衅,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大莹弊,一次不能容納全部...
    蟻前閱讀 5,186評(píng)論 0 52
  • 概述 排序有內(nèi)部排序和外部排序涤久,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序涡尘,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    閑云清煙閱讀 758評(píng)論 0 6
  • 一响迂、 單項(xiàng)選擇題(共71題) 對(duì)n個(gè)元素的序列進(jìn)行冒泡排序時(shí)考抄,最少的比較次數(shù)是( )。A. n ...
    貝影閱讀 9,075評(píng)論 0 10
  • 自從看了周梵老師的書《當(dāng)你開始愛自己全世界都會(huì)來愛你》,我就開始慢慢的自我觀察幕与、自我覺知挑势。 其實(shí)我天生具有天蝎座的...
    唱媽閱讀 719評(píng)論 0 3