javaScript排序算法學習筆記
// 用於建立數組
function createNonSortedArray(size) {
var array = new ArrayList();
for( var i = size; i>0; i--) {
array.insert(i);
}
return array;
}
function ArrayList() {
var array = [];
this.insert = function(item) {
console.log(item, 'insert');
array.push(item);
}
this.toString = function() {
console.log('tostring');
return array.join();
}
/*
* 冒泡排序
* 冒泡排序比較任何兩個相鄰的項,若是第一個比第二個大,則交換它們。
* 元素項向上移動至正確的順序,就好像氣泡升至表面同樣,冒泡排序所以得名。
* 第一輪比過以後最後一個就必定是最大的 無需再比較。因此下次要 - i
*/
this.bubbleSort = function() {
var length = array.length;
for(var i = 0;i<length;i++) {
for(var j = 0;j<length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j+1);
}
}
}
}
/*
* 選擇排序
* 選擇排序算法是一種原址比較排序算法。選擇排序大體的思路是找到數據結構中的最小值
* 並將其放置在第一位,接着找到第二小的值並將其放在第二位,以此類推。好比,第一個
* 的時候,會遍歷後面全部想跟其比較,找到最小的更其交換。因此第一個此時必定是最小的。
* 隨意第二個的時候,只會循環後面的幾個。若是找到一個比第二個更小的,那麼交換位置。
*/
this.selectionSort = function() {
var length = array.length,
indexMin;
for(var i = 0;i< length - 1;i++) {
indexMin = i;
for(var j = i;j<length;j++) {
if (array[indexMin]>array[j]) {
indexMin = j;
}
}
if (i !== indexMin) {
swap(array, i, indexMin);
}
}
}
/*
* 插入排序
* 插入排序每次排第一個數組項,以此方式構建最後的排序數組。假定第一項已經排序了,接着,
* 它和第二項進行比較,第二項是應該待在原位仍是插到第一項以前呢?這樣,頭兩項就已正確
* 排序,接着和第三項比較(它是該插入到第1、第二仍是第三位置呢?),以此類推。
* 簡而言之,就是遍歷數組的每一項,拿這一項去跟前面的項比較,若是比他小就插入到它前面。
*/
this.insertionSort = function() {
var length = array.length,
j,temp;
for (var i = 1;i<length;i++) {
j = i;
temp = array[i];
while(j>0 && array[j-1] > temp) {
array[j] = array[j - 1];
j--;
}
array[j] = temp;
}
}
// 歸併排序
// 歸併排序是一種分治算法。其思想是將原始數組切分紅較小的數組,直到每一個
// 小數組只有一個位置,接着將小數組歸併成較大的數組,直到最後一個排序完畢的大數組。
this.mergeSort = function() {
array = mergeSortRec(array);
}
var mergeSortRec = function(array) {
var length = array.length;
if (length === 1) {
return array;
}
var mid = Math.floor(length / 2),
left = array.slice(0, mid),
right = array.slice(mid, length);
return merge(mergeSortRec(left), mergeSortRec(right));
}
var merge = function(left, right) {
var result = [],
il = 0,
ir = 0;
// 完成下列操做的前提是left、right數組均已經完成。因此採用遞歸的形式
// 在數組長度爲1的時候先開始排序,而後在經過merge left與right數組
while(il < left.length && ir < right.length) {
if (left[il] < right[ir]) {
result.push(left[il++]);
} else {
result.push(right[ir++]);
}
}
// 上面是將left與right數組排完序,那麼其中之一數組必然爲空,
// 下面的操做就是將剩下的right或者left所有推入result數組中
while(il < left.length) {
result.push(left[il++]);
}
while(ir < right.length) {
result.push(right[ir++]);
}
return result;
}
// 快速排序
// 首先,從數組中選擇中間一項做爲主元
// 建立兩個指針,左邊一個指向數組的第一項,右邊一個指向數組的最後一個項。
// 移動左指針直到咱們找到一個比主元大的元素,接着,移動右指針直到找到一個
// 比主元小的元素,而後交換他們,重複這個過程,直到左指針超過右指針。這個
// 過程將使得比主元小的值都排在主元以前,而比主元大的值都排在主元以後。這一步
// 叫作劃分操做。
// 接着,算法對劃分後的小數組(較主元小的值組成的子數組,以及較主元大的值
// 組成的子數組)重複以前的兩個步驟,直到數組已徹底排序。
// 簡而言之,先分治,不斷的細化下去,到最後一個數組沒法再交換位置進行排序位置
this.quickSort = function() {
quick(array, 0, array.length - 1);
}
var quick = function(array, left, right) {
var index;
if (array.length > 1) {
index = partition(array, left, right);
if (left < index - 1 ) {
quick(array, left, index - 1);
}
if (index < right) {
quick(array, index, right);
}
}
}
var partition = function(array, left, right) {
var pivot = array[Math.floor((left + right) / 2)],
i = left,
j = right;
while(i <= j) {
while(array[i] < pivot) {
i++;
}
while(array[j] > pivot) {
j--;
}
if (i <= j) {
swap(array, i, j);
i++;
j--;
}
}
return i;
}
var swap = function(array, index1, index2) {
var aux = array[index1];
array[index1] = array[index2];
array[index2] = aux;
}
}
var array = createNonSortedArray(9);
console.log(array.toString());
array.bubbleSort();
// array.selectionSort();
// array.insertionSort();
// array.mergeSort();
// array.quickSort();
console.log(array.toString());