直接插入排序法
// 直接插入排序法
function InsertSort(array){
var len = array.length;
array.unshift(0); //左侧哨兵,防止越界
for(var i=2; i<len+1; i++){
array[0] = array[i];
var j;
for(j=i; array[j-1]>array[0]; j--){
array[j] = array[j-1];
}
array[j] = array[0];
}
array.shift(); //除掉临时变量
}
var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
InsertSort(a);
console.log(a);
希尔排序法
希尔排序法是对直接插入排序法的优化
function ShellSort(array){
var len = array.length;
var d = Math.floor(len/2); //获取分组间距
array.unshift(0); //在数组开头补多一个临时变量
while(d>0){
for(var i=d+1; i<len+1; i++ ){
array[0] = array[i];
var j;
for(j=i; j>0 && array[j-d]>array[0]; j-=d){
array[j] = array[j-d];
}
array[j] = array[0];
}
d = Math.floor(d/2);
}
array.shift(); //去除临时变量
}
var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
ShellSort(a);
console.log(a);
冒泡排序法
最简单的排序法
function bubbleSort(array){
var len = array.length;
var temp = 0;
for(var i=len-1; i>0; i--){
for(var j=0; j<i; j++){
if(array[j] > array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
bubbleSort(a);
console.log(a);
快速排序法
快速排序法相当于对冒泡排序的改进
//扫描函数
function partition(array, first, end){
var pivot = 0, temp = 0;
var p = first, q = end;
while(p<q){
while(p<q && array[p]<=array[q]) q--; //从右向左扫描
if(p<q){
temp = array[p];
array[p] = array[q];
array[q] = temp;
}
while(p<q && array[p]<=array[q]) p++; //从左向右扫描
if(p<q){
temp = array[p];
array[p] = array[q];
array[q] = temp;
}
}
pivot = p;
return pivot;
}
//快排函数
function QuickSort(array, first, end){
if(first>=end) return;
else{
//进行一轮扫描,返回一个中间值,将比中间值小的数放在中间值左侧,比中间值大的数放在中间值右侧
var pivot = partition(array, first, end);
QuickSort(array, first, pivot-1); //对左侧无序区进行快排
QuickSort(array, pivot+1, end); //对右侧无序区进行快排
}
}
var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
QuickSort(a, 0, a.length-1);
console.log(a);
选择排序法
从无序区间选择最小/最大值放到有序区间
function selectSort(array){
var len = array.length;
for(var i=0; i<len; i++){
var min = i;
for(var j=i+1; j<len; j++){
if(array[j]<array[min]){
min = j;
}
}
if(array[i] != array[min]){
var temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
}
var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
selectSort(a);
console.log(a);
堆排序
选择排序的优化版,先建堆(大根堆/小根堆),再抽出根结点放入有序区间,然后调整堆
//堆调整函数,此处使用大根堆
function sift(array, iFrom, iTo){
var i,j,temp;
i = iFrom; j = 2*i;
while(j <= iTo){
if(j < iTo && array[j] < array[j+1]) j++; //比较左右孩子,让j指向较大者
if(array[i] > array[j]) break; //根节点比左右子结点都大时,无需调整
else{
//将根节点和较大的子节点交换
temp = array[i];
array[i] = array[j];
array[j] = temp;
//进入下一层调整
i = j; j = j * 2;
}
}
}
function HeapSort(array){
var len = array.length;
var temp = 0;
var i = Math.floor(len/2);
array.unshift(0);
//初始建堆
for(; i >= 1; i--){
sift(array, i, len);
}
for(i=1; i<len; i++){
temp = array[1]; array[1]=array[len-i+1]; array[len-i+1]=temp;
sift(array, 1, len-i);
}
array.shift();
}
var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
HeapSort(a);
console.log(a);
二路归并排序(递归版)
//合并两个相邻有序的子序列,即 array[iFrom]~array[iMiddle] 与 array[iMiddle+1]~array[iTo]
function Merge(array, iFrom, iMiddle, iTo){
var assist = new Array(array.length); //合并时用的辅助存储空间
var i = iFrom; var j = iMiddle + 1; var k = iFrom;
while(i <= iMiddle && j <= iTo){
if(array[i] < array[j]) assist[k++] = array[i++]; //取array[i]和array[j]中较小者存入assist[k]
else assist[k++] = array[j++];
}
while(i <= iMiddle )
assist[k++] = array[i++];
while(j <= iTo )
assist[k++] = array[j++];
for(i = iFrom; i<= iTo; i++){
array[i] = assist[i];
}
}
//iFrom和iTo指定了排序区间
function MergeSort1(array, iFrom, iTo){
if(iFrom == iTo) return;
var iMiddle = Math.floor((iFrom+iTo)/2);
MergeSort1(array, iFrom, iMiddle);
MergeSort1(array, iMiddle+1, iTo);
Merge(array, iFrom, iMiddle, iTo);
}
var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
MergeSort1(a, 0, a.length-1);
console.log(a);