一、題幹:
請填充代碼,使mySort()能使傳入的參數按照從小到大的順序顯示出來。
function mySort() {
var tags = new Array();//使用數組作爲參數存儲容器
請補充你的代碼
return tags;//返回已經排序的數組
}
var result = mySort(50,11,16,32,24,99,57,100);/傳入參數個數不確定
console.log(result2);
二、說明
1、簡介
排序算法是用來根據元素對應的比較運算符重新排列給定的數組的算法,輸出的數組是一個根據比較符從小到大或者從大到小依次排列的數組。比較運算符是用於確定相應數據結構中元素的新順序,比如在整數數組裏面,對應的比較符號就是大於或者小於號,用戶也可以自己定義對應的比較運算符。
比如如果輸入是[4,2,3,1],按照從小到大輸出,結果應該是[1,2,3,4]
2、特性
穩定性
如果在數組中有兩個元素是相等的,在經過某個排序算法之後,原來在前面的的那個元素仍然在另一個元素的前面,那麼我們就說這個排序算法是穩定的。
如果在排序之後,原來的兩個相等元素中在前面的一個元素被移到了後面,那麼這個算法就是不穩定的。
比如排序之前數組爲[3(a),2,3(b)](其中a和b分別代表兩個不同的3),經過某個排序算法之後是[2,3(a),3(b)],那麼這個算法就是穩定的;如果變成了[2,3(b),3(a)],那麼這個算法是不穩定的。
三、解法:
基本算法
首先定義基本的交換數組元素的基本方法,節省後面的代碼量。
function swap(nums, i, j){
var temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
1、sort()
function mySort(){
var tags = new Array(); //使用數組作爲參數存儲容器
tags = [...arguments];
// for(let i = 0;i < arguments.length; i ++){
// tags.push(arguments[i]);
// }
tags.sort((a,b) => {
return a - b
})
return tags;
}
var result = mySort(50,11,16,32,24,99,57,100); //傳入參數個數不確定
console.info(result);
2、冒泡排序
冒泡排序是從左到右依次比較相鄰的兩個元素,如果前一個元素比較大,就把前一個元素和後一個交換位置,遍歷數組之後保證最後一個元素相對於前面的永遠是最大的。然後讓最後一個保持不變,重新遍歷前n-1個元素,保證第n-1個元素在前n-1個元素裏面是最大的。依此規律直到第2個元素是前2個元素裏面最大的,排序就結束了。
因爲這個排序的過程很像冒泡泡,找到最大的元素不停的移動到最後端,所以這個排序算法就叫冒泡排序。
function mySort2(){
var tags = new Array(); //使用數組作爲參數存儲容器
tags = [...arguments];
for(var i = arguments.length - 1; i >= 1; i--){
for(var j = 1; j <= i; j++){
if(tags[j-1] > tags[j]){
swap(tags,j-1,j);
}
}
}
return tags;
}
var result2 = mySort2(50,11,16,32,24,99,57,100); //傳入參數個數不確定
console.info(result2);
3、快速排序
其核心的思路是取第一個元素(或者最後一個元素)作爲分界點,把整個數組分成左右兩側,左邊的元素小於或者等於分界點元素,而右邊的元素大於分界點元素,然後把分界點移到中間位置,對左右子數組分別進行遞歸,最後就能得到一個排序完成的數組。當子數組只有一個或者沒有元素的時候就結束這個遞歸過程。
function mySort3(){
var tags = new Array(); //使用數組作爲參數存儲容器
tags = [...arguments];
quickSort(tags,0,tags.length - 1);
return tags;
}
function quickSort(nums, left, right){
if(left >= right){
return nums;
}
var low = left + 1;
var high = right;
while(low <= high){
if(nums[low] > nums[left]){
swap(nums,low,high);
high--;
}else{
low++;
}
}
low--;
swap(nums,low,left);
quickSort(nums,left,low - 1);
quickSort(nums,low + 1, right);
return nums;
}
var result3 = mySort3(50,11,16,32,24,99,57,100); //傳入參數個數不確定
console.info(result3);
方法二:
var quickSort2 = function(arr){
if(arr.length <= 1){return arr};
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex,1)[0];
var left = [];
var right = [];
for(var i = 0; i < arr.length; i++){
if(arr[i]< pivot){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
return quickSort2(left).concat([pivot],quickSort2(right));
}
4、選擇排序(選最)
選擇排序的思路比較簡單,先找到前n個元素中最大的值,然後和最後一個元素交換,這樣保證最後一個元素一定是最大的,然後找到前n-1個元素中的最大值,和第n-1個元素進行交換,然後找到前n-2個元素中最大值,和第n-2個元素交換,依次類推到第2個元素,這樣就得到了最後的排序數組。
其實整個過程和冒泡排序差不多,都是要找到最大的元素放到最後,不同點是冒泡排序是不停的交換元素,而選擇排序只需要在每一輪交換一次。
function mySort4(){
var tags = new Array(); //使用數組作爲參數存儲容器
tags = [...arguments];
for(var i = tags.length - 1; i >= 1; i --){
var max = 0;
for(var j = 0; j <= i; j++){
if(tags[max] < tags[j]){
max = j;
}
}
swap(tags,max,i);
}
return tags;
}
var result4 = mySort4(50,11,16,32,24,99,57,100); //傳入參數個數不確定
console.info(result4);
方法二:
var selectSort2 = function(arr){
for(var i = 0; i < arr.length - 1; i ++){
var min = i;
for(var j = i; j < arr.length; j ++){
if(arr[min] > arr[j]){
min = j;
}
}
swap(arr, i, min);
}
return arr;
}
5、插入排序(起撲克牌)
插入排序的核心思想是遍歷整個數組,保持當前元素左側始終是排序後的數組,然後將當前元素插入到前面排序完成的數組的對應的位置,使其保持排序狀態。有點動態規劃的感覺,類似於先把前i-1個元素排序完成,再插入第i個元素,構成i個元素的有序數組。
function mySort5(){
var tags = new Array(); //使用數組作爲參數存儲容器
tags = [...arguments];
for(var i = 1; i < arguments.length; i++){
var j = i;
while(j > 0 && tags[j] < tags[j - 1]){
swap(tags,j,j-1);
j--;
}
}
return tags;
}
var result5 = mySort5(50,11,16,32,24,99,57,100); //傳入參數個數不確定
console.info(result5);
6、歸併排序
歸併排序是典型的使用分治思想(divide-and-conquer)解決問題的案例。在排序的過程中,把原來的數組變成左右兩個數組,然後分別進行排序,當左右的子數組排序完畢之後,再合併這兩個子數組形成一個新的排序數組。整個過程遞歸進行,當只剩下一個元素或者沒有元素的時候就直接返回。
function mySort6(){
var tags = new Array(); //使用數組作爲參數存儲容器
tags = [...arguments];
mergeSort(tags,0,tags.length - 1);
return tags;
}
function mergeSort(nums, l, r){
if(l >= r){
return;
}
var mid = Math.floor((l + r)/2);
mergeSort(nums,l,mid);
mergeSort(nums,mid+1,r);
var i = l,j = mid + 1;
var n = 0;
var temp = new Array(nums.length);
while(i <= mid && j <= r){
if(nums[i] <= nums[j]){
temp[n++] = nums[i++];
}else{
temp[n++] = nums[j++];
}
}
while(i <= mid){
temp[n++] = nums[i++];
}
while(j <= r){
temp[n++] = nums[j++];
}
for(var k = 0; k < r - l + 1; k++){
nums[l + k] = temp[k];
}
// 以下代碼會使瀏覽器崩潰
// for(var k = 0; k < nums.length; k++){
// nums[l + k] = temp[k];
// }
}
var result6 = mySort6(50,11,16,32,24,99,57,100); //傳入參數個數不確定
console.log(result6);
方法二:
var mergeSort = function(arr){
var len = arr.length;
if(len < 2){
return arr;
}
var middle = Math.floor(len / 2);
var left = arr.slice(0,middle);
var right = arr.slice(middle);
return merge(mergeSort(left),mergeSort(right));
}
function merge(left,right){
var result = [];
while(left.length && right.length){
if(left[0] > right[0]){
result.push(right.shift());
}else{
result.push(left.shift())
}
}
while(left.length){
result.push(left.shift());
}
while(right.length){
result.push(right.shift());
}
return result;
}
var result6 = mergeSort([50,11,16,32,24,99,57,100]);
console.log(result6);