[算法]排序
基础排序算法大致分为三大类,选择排序、插入排序、交换排序。下面是三类排序算法的一些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;
}
作者:binking338
blog:http://www.cnblogs.com/binking338
浙公网安备 33010602011771号