1. 程式人生 > >快速排序與氣泡排序(面試題)

快速排序與氣泡排序(面試題)

今天講一道前端開發的筆試題,題目如下: 編寫快速排序和氣泡排序,並簡單對比分析.

看到題目愣了一下,知道氣泡排序,可什麼是快速排序呢?

下面先來看一下氣泡排序:

方法一: 每一次對比相鄰兩個資料的大小,小的排在前面,如果前面的資料比後面的大就交換這兩個數的位置

       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]。

總結分析:以上兩種快速排序方法的比較次數都相對少,但是隨著排序的數不一樣,比較的次數也會不一樣.

最後對氣泡排序與快速排序兩種方法進行對比分析:

以上兩種快速排序方法都比上面的氣泡排序的比較次數少,效率高。

但是氣泡排序簡單實用易於理解,而直接使用陣列方法則更加簡單快捷高效率的解決排序問題.

以上僅代表個人的見解,如果不對的地方希望大家指出.或者有更好的解決方法也希望可以分享出來學習.