快速排序與氣泡排序(面試題)
今天講一道前端開發的筆試題,題目如下: 編寫快速排序和氣泡排序,並簡單對比分析.
看到題目愣了一下,知道氣泡排序,可什麼是快速排序呢?
下面先來看一下氣泡排序:
方法一: 每一次對比相鄰兩個資料的大小,小的排在前面,如果前面的資料比後面的大就交換這兩個數的位置
var arr = [90,0,-10,88,999,100,102,2,3,20]; function sortArr1(arr){ var count = 0; //統計迴圈次數 for (let i=0;i<arr.length;i++) {//遍歷陣列,從左往右,相鄰兩個元素進行比較,把大的數往後面排 for (let j=0;j<arr.length-1-i;j++) { if(arr[j]>arr[j+1]){ var temp = arr[j+1]; //如果前面的數大於後面的則交換 arr[j+1]=arr[j]; arr[j]=temp; } document.write("第"+(++count)+"次排序後:"+arr); } } return arr; } console.log(sortArr1(arr)); //[-10, 0, 2, 3, 20, 88, 90, 100, 102, 999]
方法1執行過程中輸出的結果為:
第1次排序後:0,90,-10,88,999,100,102,2,3,20
第2次排序後:0,-10,90,88,999,100,102,2,3,20
第3次排序後:0,-10,88,90,999,100,102,2,3,20
第4次排序後:0,-10,88,90,999,100,102,2,3,20
第5次排序後:0,-10,88,90,100,999,102,2,3,20
第6次排序後:0,-10,88,90,100,102,999,2,3,20
第7次排序後:0,-10,88,90,100,102,2,999,3,20
第8次排序後:0,-10,88,90,100,102,2,3,999,20
第9次排序後:0,-10,88,90,100,102,2,3,20,999
第10次排序後:-10,0,88,90,100,102,2,3,20,999
第11次排序後:-10,0,88,90,100,102,2,3,20,999
第12次排序後:-10,0,88,90,100,102,2,3,20,999
第13次排序後:-10,0,88,90,100,102,2,3,20,999
第14次排序後:-10,0,88,90,100,102,2,3,20,999
第15次排序後:-10,0,88,90,100,2,102,3,20,999
第16次排序後:-10,0,88,90,100,2,3,102,20,999
第17次排序後:-10,0,88,90,100,2,3,20,102,999
第18次排序後:-10,0,88,90,100,2,3,20,102,999
第19次排序後:-10,0,88,90,100,2,3,20,102,999
第20次排序後:-10,0,88,90,100,2,3,20,102,999
第21次排序後:-10,0,88,90,100,2,3,20,102,999
第22次排序後:-10,0,88,90,2,100,3,20,102,999
第23次排序後:-10,0,88,90,2,3,100,20,102,999
第24次排序後:-10,0,88,90,2,3,20,100,102,999
第25次排序後:-10,0,88,90,2,3,20,100,102,999
第26次排序後:-10,0,88,90,2,3,20,100,102,999
第27次排序後:-10,0,88,90,2,3,20,100,102,999
第28次排序後:-10,0,88,2,90,3,20,100,102,999
第29次排序後:-10,0,88,2,3,90,20,100,102,999
第30次排序後:-10,0,88,2,3,20,90,100,102,999
第31次排序後:-10,0,88,2,3,20,90,100,102,999
第32次排序後:-10,0,88,2,3,20,90,100,102,999
第33次排序後:-10,0,2,88,3,20,90,100,102,999
第34次排序後:-10,0,2,3,88,20,90,100,102,999
第35次排序後:-10,0,2,3,20,88,90,100,102,999
第36次排序後:-10,0,2,3,20,88,90,100,102,999
第37次排序後:-10,0,2,3,20,88,90,100,102,999
第38次排序後:-10,0,2,3,20,88,90,100,102,999
第39次排序後:-10,0,2,3,20,88,90,100,102,999
第40次排序後:-10,0,2,3,20,88,90,100,102,999
第41次排序後:-10,0,2,3,20,88,90,100,102,999
第42次排序後:-10,0,2,3,20,88,90,100,102,999
第43次排序後:-10,0,2,3,20,88,90,100,102,999
第44次排序後:-10,0,2,3,20,88,90,100,102,999
第45次排序後:-10,0,2,3,20,88,90,100,102,999
方法二:
var times=0; function sortArr2(arr){ for(var i=0;i<arr.length-1;i++){ //遍歷陣列,獲得當前的數arr[i]與它後面的數依次對比 for(var j=i+1;j<arr.length;j++){ if(arr[i]>arr[j]){ var temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } console.log("第"+(++times)+"次排序後:"+arr); } } return arr; } console.log(sortArr2(arr)); //[-10, 0, 2, 3, 20, 88, 90, 100, 102, 999]
方法2執行過程中的結果:
第1次排序後:0,90,-10,88,999,100,102,2,3,20
第2次排序後:-10,90,0,88,999,100,102,2,3,20
第3次排序後:-10,90,0,88,999,100,102,2,3,20
第4次排序後:-10,90,0,88,999,100,102,2,3,20
第5次排序後:-10,90,0,88,999,100,102,2,3,20
第6次排序後:-10,90,0,88,999,100,102,2,3,20
第7次排序後:-10,90,0,88,999,100,102,2,3,20
第8次排序後:-10,90,0,88,999,100,102,2,3,20
第9次排序後:-10,90,0,88,999,100,102,2,3,20
第10次排序後:-10,0,90,88,999,100,102,2,3,20
第11次排序後:-10,0,90,88,999,100,102,2,3,20
第12次排序後:-10,0,90,88,999,100,102,2,3,20
第13次排序後:-10,0,90,88,999,100,102,2,3,20
第14次排序後:-10,0,90,88,999,100,102,2,3,20
第15次排序後:-10,0,90,88,999,100,102,2,3,20
第16次排序後:-10,0,90,88,999,100,102,2,3,20
第17次排序後:-10,0,90,88,999,100,102,2,3,20
第18次排序後:-10,0,88,90,999,100,102,2,3,20
第19次排序後:-10,0,88,90,999,100,102,2,3,20
第20次排序後:-10,0,88,90,999,100,102,2,3,20
第21次排序後:-10,0,88,90,999,100,102,2,3,20
第22次排序後:-10,0,2,90,999,100,102,88,3,20
第23次排序後:-10,0,2,90,999,100,102,88,3,20
第24次排序後:-10,0,2,90,999,100,102,88,3,20
第25次排序後:-10,0,2,90,999,100,102,88,3,20
第26次排序後:-10,0,2,90,999,100,102,88,3,20
第27次排序後:-10,0,2,90,999,100,102,88,3,20
第28次排序後:-10,0,2,88,999,100,102,90,3,20
第29次排序後:-10,0,2,3,999,100,102,90,88,20
第30次排序後:-10,0,2,3,999,100,102,90,88,20
第31次排序後:-10,0,2,3,100,999,102,90,88,20
第32次排序後:-10,0,2,3,100,999,102,90,88,20
第33次排序後:-10,0,2,3,90,999,102,100,88,20
第34次排序後:-10,0,2,3,88,999,102,100,90,20
第35次排序後:-10,0,2,3,20,999,102,100,90,88
第36次排序後:-10,0,2,3,20,102,999,100,90,88
第37次排序後:-10,0,2,3,20,100,999,102,90,88
第38次排序後:-10,0,2,3,20,90,999,102,100,88
第39次排序後:-10,0,2,3,20,88,999,102,100,90
第40次排序後:-10,0,2,3,20,88,102,999,100,90
第41次排序後:-10,0,2,3,20,88,100,999,102,90
第42次排序後:-10,0,2,3,20,88,90,999,102,100
第43次排序後:-10,0,2,3,20,88,90,102,999,100
第44次排序後:-10,0,2,3,20,88,90,100,999,102
第45次排序後:-10,0,2,3,20,88,90,100,102,999
總結分析:上面兩種方法都實現了氣泡排序,比較的方式不一樣,但是排序次數是一樣的,10個數要對比45次。
---------------------------------------------此處是分割線----------------------------------------------
講完氣泡排序,下面一起來了解一下什麼是快速排序,何謂快速?就是比較更少的次數得到一樣的結果。
方法一:先找到一個基準點(一般指陣列的中部),然後陣列被該基準點分為兩部分,依次與該基準點的數字比較,
如果比它小,放左邊;反之,放右邊。分別用一個空陣列去儲存比較後的資料。最後遞迴執行上述操作,直到陣列長度<=1;
var arr = [90,0,-10,88,99,1,102,2,3,200]; var times=0; var quickSort=function(arr){ //如果陣列長度小於等於1無需判斷直接返回即可 if(arr.length<=1){ return arr; } var midIndex=Math.floor(arr.length/2);//取基準點 var midIndexVal=arr.splice(midIndex,1);//取基準點的值,splice(index,1)函式可以返回陣列中被刪除的那個數arr[index+1] var left=[];//存放比基準點小的陣列 var right=[];//存放比基準點大的陣列 //遍歷陣列,進行判斷分配 for(var i=0;i<arr.length;i++){ if(arr[i]<midIndexVal){ left.push(arr[i]);//比基準點小的放在左邊陣列 console.log(left); } else{ right.push(arr[i]);//比基準點大的放在右邊陣列 console.log(right); } console.log("第"+(++times)+"次排序後:"+arr); } //遞迴執行以上操作,對左右兩個陣列進行操作,直到陣列長度為<=1; return quickSort(left).concat(midIndexVal,quickSort(right)); }; console.log(quickSort(arr)); //[-10, 0, 1, 2, 3, 88, 90, 99, 102, 200]
經過測試,隨便變換陣列的數,比較的次數也會改變,比如上面的陣列,比較了25次。
而換成[90,0,-10,88,999,1,102,2,3,200],比較了22次,結果是[-10, 0, 1, 2, 3, 88, 90, 102, 200, 999]。
再換成[90,0,-10,88,99,1,102,2,3,20] ,比較了30次,結果是[-10, 0, 1, 2, 3, 20, 88, 90, 99, 102]。
方法二:直接利用陣列的排序方法sort來實現
var count=0; function sortNumber(a,b){ //定義排序規則 console.log(count++); return a-b; } console.log(arr.sort(sortNumber)); //陣列排序方法sort
同樣的,經過測試,隨便變換陣列的數,比較的次數也會改變,比如上面的陣列[90,0,-10,88,99,1,102,2,3,200];,比較了21次。
而換成[90,0,-10,88,999,1,102,2,3,200],比較了23次,結果是[-10, 0, 1, 2, 3, 88, 90, 102, 200, 999]。
再換成[90,0,-10,88,99,1,102,2,3,20] ,比較了25次,結果是[-10, 0, 1, 2, 3, 20, 88, 90, 99, 102]。
總結分析:以上兩種快速排序方法的比較次數都相對少,但是隨著排序的數不一樣,比較的次數也會不一樣.
最後對氣泡排序與快速排序兩種方法進行對比分析:
以上兩種快速排序方法都比上面的氣泡排序的比較次數少,效率高。
但是氣泡排序簡單實用易於理解,而直接使用陣列方法則更加簡單快捷高效率的解決排序問題.
以上僅代表個人的見解,如果不對的地方希望大家指出.或者有更好的解決方法也希望可以分享出來學習.