摘要:冒泡排序就這么簡單在我大一的時候自學(xué)語言和數(shù)據(jù)結(jié)構(gòu),我當(dāng)時就接觸到了冒泡排序當(dāng)時使用的是語言編寫的。我最開始接觸的就是冒泡排序,所以這篇博文主要講的是冒泡排序。
冒泡排序就這么簡單
在我大一的時候自學(xué)c語言和數(shù)據(jù)結(jié)構(gòu),我當(dāng)時就接觸到了冒泡排序(當(dāng)時使用的是C語言編寫的)?,F(xiàn)在大三了,想要在暑假找到一份實(shí)習(xí)的工作,又要回顧一下數(shù)據(jù)結(jié)構(gòu)與算法的知識點(diǎn)了。
排序?qū)ξ覀儊碚f是一點(diǎn)也不陌生了,當(dāng)你打王者榮耀的時候也會有段位之分,當(dāng)你打Dota的時候也有天梯分。從高往下數(shù),這個排名是有規(guī)律的,就是一種排序。
我最開始接觸的就是冒泡排序,所以這篇博文主要講的是冒泡排序。
冒泡排序的實(shí)現(xiàn)來源百度百科:
冒泡排序(Bubble Sort,臺灣譯為:泡沫排序或氣泡排序)是一種簡單的排序算法。它重復(fù)地走訪過要排序的數(shù)列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數(shù)列的工作是重復(fù)地進(jìn)行直到?jīng)]有再需要交換,也就是說該數(shù)列已經(jīng)排序完成。這個算法的名字由來是因?yàn)樵酱蟮脑貢?jīng)由交換慢慢“浮”到數(shù)列的頂端,故名。
算法描述:
i從0開始,i與i+1比較,如果i>i+1,那么就互換
i不斷增加,直到i
從最簡單開始,首先我們創(chuàng)建一個數(shù)組,該數(shù)組有5位數(shù)字:
int[] arrays = {2, 5, 1, 3, 4};一、第一趟排序
下面我們根據(jù)算法的描述來進(jìn)行代碼驗(yàn)算(第一趟排序):
//使用臨時變量,讓兩個數(shù)互換 int temp; //第一位和第二位比 if (arrays[0] > arrays[1]) { //交換 temp = arrays[0]; arrays[0] = arrays[1]; arrays[1] = temp; } //第二位和第三位比 if (arrays[1] > arrays[2]) { temp = arrays[1]; arrays[1] = arrays[2]; arrays[2] = temp; } //第三位和第四位比 if (arrays[2] > arrays[3]) { temp = arrays[2]; arrays[2] = arrays[3]; arrays[3] = temp; } //第四位和第五位比 if (arrays[3] > arrays[4]) { temp = arrays[3]; arrays[3] = arrays[4]; arrays[4] = temp; }
如果前一位的數(shù)比后一位的數(shù)要大,那么就交換,直到將數(shù)組的所有元素都比較了一遍!
經(jīng)過我們第一趟比較,我們可以發(fā)現(xiàn):最大的值就在數(shù)組的末尾了!
一、第二趟排序第二趟排序跟第一趟排序一樣,也是用前一位與后一位比較,如果前一位比后一位要大,那就交換。值得注意的是:并不需要與最后一位比較了,因?yàn)樵诘谝惶伺判蛲炅?,最后一位已?jīng)是最大的數(shù)了。同理,我們第二趟排序完了之后,倒數(shù)第二位也是第二大的數(shù)了。
第二趟排序的代碼如下:
//第一位和第二位比 if (arrays[0] > arrays[1]) { //交換 temp = arrays[0]; arrays[0] = arrays[1]; arrays[1] = temp; } //第二位和第三位比 if (arrays[1] > arrays[2]) { temp = arrays[1]; arrays[1] = arrays[2]; arrays[2] = temp; } //第三位和第四位比 if (arrays[2] > arrays[3]) { temp = arrays[2]; arrays[2] = arrays[3]; arrays[3] = temp; } //第四位不需要和第五位比了,因?yàn)樵诘谝惶伺判蚪Y(jié)束后,第五位是最大的了。
結(jié)果:我們的第二大數(shù)已經(jīng)排在了倒數(shù)第二位了
三、代碼簡化值得說明的是:上面的結(jié)果看起來已經(jīng)是排序好的了,其實(shí)是我在測試時數(shù)據(jù)還不足夠亂,如果數(shù)據(jù)足夠亂的話,是需要4(n-1)趟排序的!
但我們從上面的代碼就可以發(fā)現(xiàn):第一趟和第二趟的比較、交換代碼都是重復(fù)的,并且我們的比較都是寫死的(0,1,2,3,4),并不通用!
我們的數(shù)組有5位數(shù)字
第一趟需要比較4次
第二趟需要比較3次
我們可以根據(jù)上面規(guī)律推斷出:
第三趟需要比較2次
第四躺需要比較1次
再從上面的規(guī)律可以總結(jié)出:5位數(shù)的數(shù)組需要4躺排序的,每躺排序之后次數(shù)減1(因?yàn)榍耙惶艘呀?jīng)把前一趟數(shù)的最大值確定下來了)!
于是我們可以根據(jù)for循環(huán)和變量將上面的代碼進(jìn)行簡化:
int temp; //外層循環(huán)是排序的趟數(shù) for (int i = 0; i < arrays.length - 1 ; i++) { //內(nèi)層循環(huán)是當(dāng)前趟數(shù)需要比較的次數(shù) for (int j = 0; j < arrays.length - i - 1; j++) { //前一位與后一位與前一位比較,如果前一位比后一位要大,那么交換 if (arrays[j] > arrays[j + 1]) { temp = arrays[j]; arrays[j] = arrays[j + 1]; arrays[j + 1] = temp; } } }四、冒泡排序優(yōu)化
從上面的例子我們可以看出來,如果數(shù)據(jù)足夠亂的情況下是需要經(jīng)過4躺比較才能將數(shù)組完整排好序。但是我們在第二躺比較后就已經(jīng)得到排好序的數(shù)組了。
但是,我們的程序在第二趟排序后仍會執(zhí)行第三趟、第四趟排序。這是沒有必要的,因此我們可以對其進(jìn)行優(yōu)化一下:
如果在某躺排序中沒有發(fā)生交換位置,那么我們可以認(rèn)為該數(shù)組已經(jīng)排好序了。
這也不難理解,因?yàn)槲覀?strong>每趟排序的目的就是將當(dāng)前趟最大的數(shù)置換到對應(yīng)的位置上,沒有發(fā)生置換說明就已經(jīng)排好序了。
代碼如下:
//裝載臨時變量 int temp; //記錄是否發(fā)生了置換, 0 表示沒有發(fā)生置換、 1 表示發(fā)生了置換 int isChange; //外層循環(huán)是排序的趟數(shù) for (int i = 0; i < arrays.length - 1; i++) { //每比較一趟就重新初始化為0 isChange = 0; //內(nèi)層循環(huán)是當(dāng)前趟數(shù)需要比較的次數(shù) for (int j = 0; j < arrays.length - i - 1; j++) { //前一位與后一位與前一位比較,如果前一位比后一位要大,那么交換 if (arrays[j] > arrays[j + 1]) { temp = arrays[j]; arrays[j] = arrays[j + 1]; arrays[j + 1] = temp; //如果進(jìn)到這里面了,說明發(fā)生置換了 isChange = 1; } } //如果比較完一趟沒有發(fā)生置換,那么說明已經(jīng)排好序了,不需要再執(zhí)行下去了 if (isChange == 0) { break; } }五、擴(kuò)展閱讀
C語言實(shí)現(xiàn)第一種方式:
void bubble ( int arr[], int n) { int i; int temp; for (i = 0; i < n - 1; i++) { if (arr[i] > arr[i + 1]) { temp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = temp; } } } void bubbleSort ( int arr[], int n) { int i; for (i = n; i >= 1; i--) { bubble(arr, i); } }
C語言實(shí)現(xiàn)第二種方式遞歸:
void bubble ( int arr[], int L, int R) { if (L == R) ; else { int i; for (i = L; i <= R - 1; i++)//i只能到達(dá)R-1 if (arr[i] > arr[i + 1]) { int temp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = temp; } bubble(arr, L, R - 1);//第一輪已排好R } }
測試代碼:
int main () { int arr[] = {2, 3, 4, 511, 66, 777, 444, 555, 9999}; bubbleSort(arr, 8); for (int i = 0; i < 9; i++) cout << arr[i] << endl; return 0; }5.1時間復(fù)雜度的理解:
https://www.zhihu.com/question/21387264
https://www.jianshu.com/p/f4cca5ce055a
如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68818.html
摘要:選擇排序就這么簡單從上一篇已經(jīng)講解了冒泡排序了,本章主要講解的是選擇排序,希望大家看完能夠理解并手寫出選擇排序的代碼,然后就通過面試了如果我寫得有錯誤的地方也請大家在評論下指出。 選擇排序就這么簡單 從上一篇已經(jīng)講解了冒泡排序了,本章主要講解的是選擇排序,希望大家看完能夠理解并手寫出選擇排序的代碼,然后就通過面試了!如果我寫得有錯誤的地方也請大家在評論下指出。 選擇排序介紹和穩(wěn)定性說明...
摘要:比較函數(shù)應(yīng)該具有兩個參數(shù)和,其返回值如下若小于,在排序后的數(shù)組中應(yīng)該出現(xiàn)在之前,則返回一個小于的值。把這個安排好,再繼續(xù)之前的冒泡排序。 受大學(xué)室友的鼓動,我也打算利用公眾平臺來記錄自己的前端知識積累,同時呢,自己總結(jié)的東西,總歸會有局限性,希望小伙伴能給我指點(diǎn)迷津。知識就是一張巨大的網(wǎng),作為一名摸不清頭緒的入學(xué)者,唯一能做的事情就是吐好每一根絲,絲擰成線,線再織成網(wǎng)。好啦,開機(jī)儀式o...
摘要:那么,有了循環(huán),為什么還要用遞歸呢在某些情況下費(fèi)波納切數(shù)列,漢諾塔,使用遞歸會比循環(huán)簡單很多很多話說多了也無益,讓我們來感受一下遞歸吧。 遞歸介紹 本來預(yù)算此章節(jié)是繼續(xù)寫快速排序的,然而編寫快速排序往往是遞歸來寫的,并且遞歸可能不是那么好理解,于是就有了這篇文章。 在上面提到了遞歸這么一個詞,遞歸在程序語言中簡單的理解是:方法自己調(diào)用自己 遞歸其實(shí)和循環(huán)是非常像的,循環(huán)都可以改寫成遞歸...
摘要:數(shù)組就是一個簡單的線性序列,這使得元素訪問非??焖佟6褏^(qū)堆內(nèi)存用來存放創(chuàng)建的對象和數(shù)組。堆內(nèi)存中的實(shí)體不再被指向時,啟動垃圾回收機(jī)制,自動清除,這也是優(yōu)于的表現(xiàn)之一中需要程序員手動清除。 showImg(https://segmentfault.com/img/remote/1460000019264541?w=600&h=242); 第三章 方法和數(shù)組 3.1 概述 還記得我們的He...
摘要:用來標(biāo)示該輪冒泡排序中,數(shù)組是否是有序的。適用情況當(dāng)冒泡算法運(yùn)行到后半段的時候,如果此時數(shù)組已經(jīng)有序了,需要提前結(jié)束冒泡排序。當(dāng)?shù)谝惠喢芭菖判蚪Y(jié)束后,元素會被移動到下標(biāo)的位置。 這篇文章包含了你一定知道的,和你不一定知道的冒泡排序。 gif看不了可以點(diǎn)擊【原文】查看gif。 源碼: 【地址】 1. 什么是冒泡排序 可能對于大多數(shù)的人來說比如我,接觸的第一個算法就是冒泡排序。 我看過的很...
閱讀 4388·2021-11-22 09:34
閱讀 2703·2021-11-12 10:36
閱讀 753·2021-08-18 10:23
閱讀 2649·2019-08-30 15:55
閱讀 3132·2019-08-30 15:53
閱讀 2093·2019-08-30 15:44
閱讀 1370·2019-08-29 15:37
閱讀 1419·2019-08-29 13:04