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