基础排序算法大致分为三大类,选择排序、插入排序、交换排序。下面是三类排序算法的一些javascript实现整理。
选择排序
简单选择排序
// 选择排序 function selection_sort(arr) { var n = arr.length; var i, j, min, t; for( i =0; i < n -1; i ++) { min = i; // 查找最小值 for( j = i +1; j < n; j ++) if( arr[min] > arr[j])min = j; // 交换 if( min != i) { t = arr[min]; arr[min] = arr[i]; arr[i] = t; } } return arr; }
堆排序
// 堆排序(选择排序一种) function heap_sort(arr) { // arr是待调整的堆数组,i是待调整的数组元素的位置,n是数组的长度 // 本函数功能:根据数组arr构建大根堆(每一个分支从根到叶子都是递减,根最大) function heap_adjust(arr, i, n) { var child; var t; for (t = arr[i]; 2 * i + 1 < n; i = child) { // 子结点的位置=2*(父结点位置)+ 1 child = 2 * i + 1; // 得到子结点中较大的结点 if ( child < n-1 && arr[child + 1] > arr[child]) ++child; // 如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点,下个循环比较替换后的分支 if (t < arr[child]) { arr[i] = arr[child]; arr[child]= t; } else // 否则退出循环 break; } } var n = arr.length; var t; // n/2-1是倒数第一个非叶节点 // 调整数的每一个分支使得每一个分支从根到叶子都是大到小排列 for (var i = n / 2 - 1; i >= 0; --i) heap_adjust(arr, i, n); // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 for (var i = n - 1; i > 0; --i) { // 把第一个元素和当前的最后一个元素交换, // 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的 t = arr[i]; arr[i] = arr[0]; arr[0] = t; // 取出二叉树的第二层中较大数上升至根节点,根节点下沉至较大数分支,更新该分支,将值下沉至合适位置。 heap_adjust(arr, 0, i); } return arr; }
插入排序
直接插入排序
// 直接插入排序算法 function insertion_sort(arr) { var n = arr.length; var t, j; // 循环从第二个数组元素开始,arr[0]作为最初已排序部分 for(var i=1;i<n;i++) { // 挖出arr[i] (t标记为未排序第一个元素) t=arr[i]; j=i-1; // 将t与已排序元素从大到小比较,寻找t应插入的位置 while (j>=0 && arr[j]>t) { arr[j+1]=arr[j]; j--; } arr[j+1]=t; } return arr; }
希尔排序
// 希尔排序(插入排序一种) function shell_sort(arr) { var n = arr.length; var fraction,i,j,t; // 取数组1/2作为初始增量 for(fraction=Math.floor(n/2); fraction>0; fraction=Math.floor(fraction/2)) { for(i = fraction; i<n; i++ ) { for(j = i-fraction; j>=0 && arr[j]>arr[fraction+j]; j-=fraction ) { t = arr[j]; arr[j] = arr[fraction+j]; arr[fraction+j] = t; } } } return arr; }
合并排序
// 合并排序(本人认为也是插入排序一种) function merge_sort(arr, s, e, b){ s = s || 0; e = e || arr.length - 1; b = b || new Array(arr.length); if (s >= e) return; var m = (s + e) >> 1; merge_sort(arr, s, m, b); merge_sort(arr, m + 1, e, b); for (var i = s, j = s, k = m + 1; i <= e; ++i) b[i] = arr[(k > e || j <= m && arr[j] < arr[k]) ? j++ : k++]; for (var i = s; i <= e; ++i) arr[i] = b[i]; }
交换排序
冒泡排序
// 冒泡排序(交换排序一种) function bubble_sort(arr){ var t,i,j; // 一共比较n-1趟 for(i=0;i<arr.length-1;i++){ // 对当前无序区arr[i..n]自左向右扫描 for(j=0;j<arr.length-i-1;j++){ if(arr[j]>arr[j+1]){ //交换 t=arr[j]; arr[j]=arr[j+1]; arr[j+1]=t; } } } return arr; }
快速排序
// 递归实现快速排序(交换排序一种) function quick_sort(arr, l, r) { var i,j,x; l = l || 0; r = r || arr.length-1; if (l < r) { i = l, j = r, x = arr[l]; while (i < j) { // 从右向左找第一个小于x的数 while(i < j && arr[j] >= x) j--; if(i < j) arr[i++] = arr[j]; // 从左向右找第一个大于等于x的数 while(i < j && arr[i] < x) i++; if(i < j) arr[j--] = arr[i]; } arr[i] = x; quick_sort(arr, l, i - 1); // 递归调用 quick_sort(arr, i + 1, r); } return arr; }
// 栈式实现快速排序(交换排序一种) function stack_quick_sort(arr) { var stack = [0, arr.length - 1]; var i,index,e,t; while (stack.length > 0){ e = stack.pop(), s = stack.pop(); if (s >= e) continue; t = arr[(s + e) >> 1]; arr[(s + e) >> 1] = arr[e]; arr[e] = t; index = s - 1; for (i = s; i <= e; ++i){ if (arr[i] <= arr[e]){ ++index; t = arr[i]; arr[i] = arr[index]; arr[index] = t; } } stack.push(s, index - 1, index + 1, e); } return arr; }