成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

新聞 前端 算法
程序bug也能負(fù)負(fù)得正嗎?比如程序員們再熟悉不過的排序算法,通過兩個“bug”居然能歪打正著,實(shí)在令人匪夷所思。

 本文經(jīng)AI新媒體量子位(公眾號ID:QbitAI)授權(quán)轉(zhuǎn)載,轉(zhuǎn)載請聯(lián)系出處。

[[427437]]

程序bug也能負(fù)負(fù)得正嗎?

還真可以。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

比如程序員們再熟悉不過的排序算法,通過兩個“bug”居然能歪打正著,實(shí)在令人匪夷所思。

請看這位程序員寫的數(shù)組升序排序代碼:

  1. for i = 1 to n do 
  2. for j = 1 to n do 
  3. if A[i] < A[j] then 
  4. swap A[i] and A[j] 

今天這串代碼在Hacker News論壇上突然火了起來,引來大批程序員圍觀。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

乍一看這段代碼,你的反應(yīng)會是什么?會不會覺得這個程序員水平太差了,連基本的冒泡算法都寫不好:

不等號方向錯了,第二層循環(huán)指數(shù)j的范圍也弄錯了。

總之,這段代碼“絕對不可能正確”。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

△冒泡算法

但如果你真的運(yùn)行一下會發(fā)現(xiàn),結(jié)果還真的是按照升序排列的。

我們再來看一下正確的冒泡算法代碼是怎樣的:

  1. for i = 1 to n do 
  2. for j = i + 1 to n do 
  3. if A[i] > A[j] then 
  4. swap A[i] and A[j] 

后者不同之處是j = i + 1且A[i] > A[j] ,兩段程序大相徑庭。

然而我要告訴你一個不可思議的事實(shí),其實(shí)第一串代碼是對的,而且可以嚴(yán)格證明。

那么它是如何實(shí)現(xiàn)正確排序的?

為何能歪打正著

仔細(xì)一想,其實(shí)很容易理解。因?yàn)樵撍惴ū让芭菖判蚨嘁话虢粨Q操作,正好可以將降序編程升序。

不過,作者還是給出了嚴(yán)格的證明。

我們定義Pᵢ是經(jīng)過i次(1 ≤ i ≤ n)外循環(huán)后得到的數(shù)組。

如果算法正確,那么前i項(xiàng)已經(jīng)是升序排列,即A[1] ≤ A[2] ≤ . . . ≤ A[i]。

證明該算法正確,實(shí)際上就是證明Pₙ對于任何n都成立。

根據(jù)數(shù)學(xué)歸納法,我們只要證明P₁成立,假設(shè)Pᵢ成立,接著再證明Pi+1也成立,命題即可得證。

P₁顯然是正確的,而且這一步和普通的冒泡算法降序沒有區(qū)別,經(jīng)過第1次外循環(huán),A[1]就是整個數(shù)組的最大元素。

接著我們假設(shè)Pᵢ成立,然后證明Pi+1成立。

我們先定義一個序數(shù)k:

首先假設(shè)A[k](k介于1~i之間)滿足A[k]>A[i+1]最小的一個數(shù),那么A[k−1]≤A[i+1](k≠1)。

如果A[i+1]≥A[i],那么這樣的k不存在,我們就令k=i+1。

考慮以下三種情況:

1、1 ≤ j ≤ k−1

由于A[i+1]>A[j],沒有任何元素交換發(fā)生。

2、 k ≤ j ≤ i (如果k=i+1,則不存在此步驟)

由于A[j]>A[i+1],所以每次比較后都會有元素交換發(fā)生。

我們使用A[ ]和A′[ ]來表示交換前和交換后的元素,所以

A′[i+1] = A[k],A′[k]=A[i+1]

經(jīng)過一系列交換,最大元素最終被放到了A[i+1] 位置上,原來的A[i+1]變成了最大元素,A[k]被插入了大小介于原來A[k]和A[k-1]之間的元素。

3、i+1 ≤ j ≤ n

由于最大元素已經(jīng)交換到前i+1個元素中,此過程也沒有任何元素交換。

最后,Pₙ就是升序排序算法執(zhí)行完以后的結(jié)果。

由于內(nèi)外兩組循環(huán)沒有任何范圍差別,因此這可以說是“最簡單”的排序算法了。

從代碼上來看,它很像冒泡算法,但從證明過程中可以看出,這實(shí)際上是一種插入算法。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

△插入算法

算法復(fù)雜度

顯然,該算法總會進(jìn)行次比較,接下來計(jì)算算法的交換次數(shù)。

可以證明交換其次最多為I+2(n-1),最少為n-1。

其中I為初始數(shù)字的逆序數(shù),最大為n(n-1)/2

因此整個算法的復(fù)雜度為O(n²)。

從證明過程中可以看出,除了i=1的循環(huán)以外,其余循環(huán)里j=i-1之后的部分完全無效,因此可以將這部分省略,得到簡化后的算法。

  1. for i = 2 to n do 
  2. for j = 1 to i − 1 do 
  3. if A[i] < A[j] then 
  4. swap A[i] and A[j] 

該算法減少了比較和交換次數(shù),不過算法復(fù)雜度依然是O(n²)。

網(wǎng)友:這個算法我以前見過

比最容易理解的冒泡算法還要簡單,這個排序算法在Hacker News上很快引起了網(wǎng)友的圍觀。

不少人覺得它“很眼熟”。

有位網(wǎng)友表示,自己曾在奧林匹克數(shù)學(xué)競賽中看到一個同學(xué)用了一種非常奇怪的排序算法,它可以運(yùn)行但是效率很低,更像是一種插入排序。

如果我沒記錯的話,他用的就是這種算法。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

事實(shí)上,關(guān)于這種算法的討論已久,從2014年開始就不斷有人發(fā)帖,這次作者將論文上傳到arXiv后又引起了廣泛熱議。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

甚至還有烏龍事件發(fā)生。

有位網(wǎng)友掃了一眼論文就以為這個算法和自己10年前提出的一樣。

留言網(wǎng)友的算法:

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

乍一看兩種算法的代碼確實(shí)很像,原理上的確有些相似。

都是看起來像冒泡排序,但其實(shí)更貼近選擇排序。

不過很快有人指出真相:這種算法中 j=i+1 to n,并且是當(dāng) A[i] > A[j] 時交換。

而作者提出的算法中 j=1 to n,A[i] < A[j] 時交換。

兩種算法相比,網(wǎng)友此前提出的更容易被理解為什么可以運(yùn)行。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

當(dāng)然也有歪樓的,有人就調(diào)侃自己剛學(xué)編程時寫過這個算法。

我百分百確定,在我剛開始學(xué)編程、并想要找到最短的排序方法時就寫過它。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的
[[427441]]

不過說到實(shí)際應(yīng)用上,這種算法需要的計(jì)算時間太長了。

有人就認(rèn)為,這種算法此前被發(fā)現(xiàn)過很多次,但是那些人根本沒打算用它。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

也有人提出:這種排序沒有睡眠排序簡單。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的

睡眠排序就是構(gòu)造n個線程,讓線程和排序的n個數(shù)對應(yīng)。

例如對于[4,2,3,5,9]這樣一組數(shù)字,就創(chuàng)建5個線程,每個線程睡眠4s,2s,3s,5s,9s。這些線程睡醒之后,就把自己對應(yīng)的數(shù)報出來即可。這樣等所有線程都醒來,排序就結(jié)束了。

但和作者提出的算法一樣,睡眠排序由于多線程的問題,在真正實(shí)現(xiàn)上也有困難

此外,這位網(wǎng)友也表示自己看到過這種算法:

我確定我此前看到過這種算法,它沒有名字嗎?

很快就有人提議說——

如果它沒有名字的話,我建議稱之為“面試排序”。

比冒泡算法還簡單的排序算法:看起來滿是bug的程序,居然是對的
 

 

 

責(zé)任編輯:張燕妮 來源: 量子位
相關(guān)推薦

2021-02-02 13:23:47

Python語言線程

2014-11-07 10:26:05

2023-08-29 08:01:39

2020-06-29 15:00:31

UbuntumacOSLinux

2021-01-22 09:11:34

Python多線程CPU

2019-08-09 10:15:07

程序員項(xiàng)目研發(fā)

2013-12-30 10:06:51

智能硬件3D打印互聯(lián)網(wǎng)化

2016-08-01 11:33:40

云遷移云安全合規(guī)性

2022-02-28 12:57:09

GNOMEPlasma桌面

2021-10-02 10:36:00

YAML編程語言軟件開發(fā)

2024-05-20 08:45:46

2024-03-08 12:20:25

Python代碼

2025-03-12 10:36:32

2021-09-29 00:19:10

容器集群k8s

2022-02-21 12:05:49

LibreOffiLinux工具欄

2022-03-30 14:23:48

LibreOfficOffice開源

2021-02-27 21:45:22

程序代碼函數(shù)

2021-08-02 15:06:46

vim服務(wù)Java

2022-01-22 16:25:51

System76桌面應(yīng)用

2021-06-02 16:19:14

技術(shù)研發(fā)指標(biāo)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产综合在线视频 | 欧美日韩中文国产一区发布 | 国产亚洲成av人片在线观看桃 | 欧美精品久久久 | 亚洲成人福利在线观看 | 精品国产一区二区三区在线观看 | 成人在线播放网址 | 国产精品久久久久久久久久 | 日韩在线视频免费观看 | 美女逼网站 | 久久尤物免费一区二区三区 | 天天躁日日躁狠狠躁2018小说 | 99久久日韩精品免费热麻豆美女 | 久久亚洲天堂 | 91高清视频在线观看 | 偷派自拍 | 成人免费视频网站在线观看 | 国产免费一区二区 | 国产精品日韩欧美一区二区三区 | 欧美日韩一区精品 | 水蜜桃久久夜色精品一区 | 久久99精品久久久久久国产越南 | 国产美女一区二区 | 日韩免费看视频 | 久久久久久久久综合 | 日本在线中文 | 日韩中文字幕一区二区 | 精品免费看 | 亚洲一区二区中文字幕在线观看 | 成人99 | 日本高清视频在线播放 | 国产精品 亚洲一区 | 黄色免费观看网站 | 欧美精品乱码久久久久久按摩 | 亚洲视频在线看 | 天天久久 | 久草成人网 | 精品国产乱码久久久久久丨区2区 | 国产一区不卡 | 不用播放器看的av | 国产精品久久久久久久7电影 |