DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 排序算法的javascript實現與講解(99js手記)
排序算法的javascript實現與講解(99js手記)
編輯:關於JavaScript     

冒泡排序

冒泡的原理是讓最大元素或者最小元素”浮起來“

插入排序,選擇排序,快速排序,冒泡排序都是比較排序

思路

依次比較相鄰的兩個數,將小數放在前面,大數放在後面。

step1:比較第1個和第2個數,將小數放前,大數放後。比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後。
step2:在第二趟:仍從第一對數開始比較(因為可能由於第2個數和第3個數的交換,使得第1個數不再小於第2個數),將小數放前,大數放後,一直比較到倒數第二個數(倒數第一的位置上已經是最大的),第二趟結束,在倒數第二的位置上得到一個新的最大數(其實在整個數列中是第二大的數)。
如此下去,重復以上過程,直至最終完成排序。
由於在排序過程中總是小數往前放,大數往後放,相當於氣泡往上升,所以稱作冒泡排序。
冒泡排序的動畫效果

實現:此段代碼比較簡單,是屬於算法裡面最基礎最基礎最基礎的代碼。。。
要注意三點

1.交換類的方法在javascript中可以用 a=[b,b=a][0] 這個非常巧妙的方法來解決,
代替

復制代碼 代碼如下:
var,a,b,temp
temp = a;
a=b;
b = temp

這種交換方法
2.要注意循環變量的緩存,這裡緩存了array.length
3.要注意內嵌的那個循環,是從第一個數比較到倒數第n個數,n則為比較的step數

function bubbleSort(array) {
var l=array.length;
for (var i = 0; i < l; i++) {//比較的step數為數組的長度
for (var j = 0; j < l-i; j++) {//內嵌交換的次數是從第一個數比較到倒數第總長-n個數,n則為比較的step數
if (array[j] < array[j - 1]) {
array[j] = [array[j - 1], array[j - 1] = array[j]][0]//在這裡交換元素
}
}
for (var k = 0; k < l; k++) {
console.log(array[k] + ",");
}
console.log('這是第'+(i+1)+'次排序')
}
}
var a = [6,54,6,22,5,7,8,2,34];
bubbleSort(a);

動畫效果

插入排序(Insertion Sort)
非常簡單,就是我們摸牌插牌的步驟!
思路:

1首先假設我們摸了一張牌,我們手裡目前所有牌設為empty = []摸了一張push(arr[0])
2取出下一個牌,設為a,在我們所有的牌empty(已經排序)從後向前掃描
3如果手裡這張牌empty[empty.length-n](已排序)大於新元素,將該牌移到下一位置(騰空間)empty[empty.length-n]= empty[empty.length-n+1]
4重復步驟3,直到找到已排序的牌empty[empty.length-n]小於或者等於a
5將a插入到該位置中 empty[empty.length-n]=a
6重復步驟2
但是javascript代碼實現起來還是稍微有些難度的,代碼如下:

function insert(arr) {
var l = arr.length;
var empty = [];//空數組,表示我們的手
empty.push(arr[0]);//我們先摸起來一張
for (var i = 1; i < l; i++) {//注意這裡起點是1,因為我們已經摸了一張了!
if (arr[i] > empty[empty.length - 1]) {
empty[empty.length] = arr[i]
} //如果比有序數組empty還大,直接放到末尾
for (var j = empty.length; j > 0 && arr[i] < empty[j - 1]; j--) { //從最大值跟arr進行比較,為了給arr騰空。當arr<有序數組的某一位時,就不用移動了。
empty[j] = empty[j - 1]; //向右移動
empty[j - 1] = arr[i]; //把值放到空出來的位置上
}
//console.log(empty)
}
return empty
}

那麼這裡比較重要的知識點是&&符號,表示“與”,即兩邊的條件都要滿足,表達式才成立。
&&符號也可以代替if比如 if(a){fun()} 等於 a&&b
另外一點非常重要
設數組是arr,則他的“最後一項” 是arr[arr.length-1]。

排序動畫


選擇排序(Selection sort)
也是一種簡單的排序算法。

思路:

把最小元素找出來-扔到數組裡-再找次小的-扔到數組裡,以此類推。
首先在未排序數組中找到最小元素,找的方法可以利用不斷判斷並賦值的手段,即:設數組第一個元素array[0]為最小元素,那麼“最小元素”在數組中的序號就為0
之後遍歷數組,若數組第二個元素比他還要小,那麼說明第二個為最小元素,把“0” 更新為“1”。
遍歷完畢後,我們就知道這一系列的最小元素下標為“n”;直接拿出來存放到排序序列的起始位置(array[n])
然後,再從剩余未排序元素中繼續尋找最小元素,然後放到排序序列末尾。注意,此時遍歷的下標就從1開始了。因為我們已經挑出了一個最小元素了。
以此類推,直到所有元素均排序完畢。

function selectSort(array) {
var min;
var l = array.length;//緩存長度
for (var i = 0; i < l; i++) {//開始進行循環,一共循環l次,就可以找出l個元素了
min = i;//假設第一個為最小元素
for (var j = i + 1; j < l; j++) {//從第一個開始循環,遍歷
if (array[min] > array[j])//判斷之後的是否比前面的小
min = j;//更新“最小”的下標
}
if (min != i) {//這裡因為是在同一個數組內進行操作,所以直接交換元素即可。比如數組第一項是i,那麼我找出了最小元素為array[min],那麼我就需要把這個min跟i交換。以此類推。
array[i]= [array[min],array[min]=array[i]][0];//交換元素
}
}
return array;
}

這裡仍然注意的是交換的寫法 array[i]= [array[min],array[min]=array[i]][0]
可以方便的把array[i]與array[min]交換~

排序動畫

快速排序
 
快速排序是目前最強大的排序算法,算法利用了遞歸的思想。
 
思路

從數組中挑出一個元素,稱為 “基准”,這個可以直接利用length/2挑出來
遍歷數組,所有元素比基准值小的擺放在基准前面,所有元素比基准值大的擺在基准的後面(相同的數可以到任一邊)。通俗來講:男的站左邊,女的站右邊。。
之後我們得到了一個這樣的數組 array= 比基准小的部分組成的數組lArray+基准+比基准大的部分組成的數組rArray。
那麼我們之後只需要再把lArray,rArray進行“同樣的”處理即可~
這就需要用到 遞歸 的寫法了。處理之後,lArray又分成了 lArray的基准,比lArray基准還小的,比lArray基准還大的。。
那麼我們不斷的進行操作,男的站左邊,女的站右邊。。
直到我們發現,lArray的長度變成1了,不足以再分下去了,我們認為排序結束。

function quickSort(arr) {
var l = arr.length;//緩存數組長度
if(arr.length <= 1){return arr}; //如果我們拿到的lArray,rArray長度比1都小,那就不用排了~
var num = Math.floor(arr.length / 2);//取數組中間的那個數。注意length/2不一定是整數,用Math.floor取整
var numValue = arr.splice(num, 1)[0];//利用splice方法,取一個元素出來,注意語法
var left = [];//創建左邊基准容器
var right = [];//創建右邊基准容器
for (var i = 0; i < l; i += 1) {//開始遍歷數組
arr[i] < numValue ? left.push(arr[i]) : right.push(arr[i]);//男的站左邊,女的站右邊。。
}
return quickSort(left).concat([numValue], quickSort(right))//遞歸,繼續對左右數組進行操作。
}

動畫效果:

這裡注意 arr.splice(num,1)雖然只抽了一個數,但splice的結果也是數組,需要[0],要不然結果就會很奇葩的出現一堆array(1)的數組了。。。
splice的參考:http://www.jb51.net/w3school/js/jsref_splice.htm
Math.floor即Math對象的參考http://www.jb51.net/w3school/js/js_obj_math.htm
遞歸是什麼:http://baike.baidu.com/view/96473.htm

以上四個算法除了快速排序,都是簡單排序算法,而這四個算法在面試中考的都非常頻繁~
在這裡仍然要強調一點,以上的算法大量使用了循環及數組的相關知識,一定要背熟!

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved