数据结构与算法的JavaScript描述——高级排序算法(3)
说明:以下部分均为《数据结构与算法的JavaScript描述》学习内容及笔记。
希尔排序
希尔排序
的核心理念与插入排序不同,他会首先比较距离较远的元素,而非相邻的元素。和简单的比较相邻元素相比,使用这种方案可以使离正确位置很远的元素更快的回到合适的位置。当开始用这个算法遍历数据集时,所有元素之间的距离会不断减少,直到处理到数据集的末尾,这时算法比较的就是相邻的元素了。- 通过定义一个间隔序列来表示在排序过程中进行比较的元素之间有多远的间隔。
- 算法在第一次处理数据集的时候,会检查所有间隔为
h
(如:5)的元素。下一次遍历会检验所有间隔为h
(如:3)的元素。最后一次则会对间隔为1
的元素,也就是相邻元素执行插入排序。在最后一次处理时,大部分元素都将在正确的位置,算法就不必对很多元素进行交换。这也就是希尔排序比插入排序更高效的地方。
function shellSort(){
var N=this.dataStore.length;
var h=1;
while(h < N/3){
h=3 * h + 1;
}
while(h >= 1){
for(var i=h;i<N;i++){
for(var j=i;j>=h &&this.dataStore[j]<this.dataStore[j-h];j-=h){
swap(this.dataStore, j, j-h);
}
}
h=(h-1)/3;
}
}
* 归并排序
1 自顶向下的归并排序
通常来讲,归并排序会使用递归的算法来实现。然而,在JavaScript中这种方式不太可行,因为这个算法的
递归深度对它来讲太深了
。
2 自底向上的归并排序
首先将数据集分解为一组只有一个元素的数组。然后通过创建一组左右子数组将他们慢慢合并起来,每次合并都保存一部分排好序的数据,直到最后剩下的这个数组所有的数据都完美排序。
function mergeSort(arr){
if(ar.length<2){
return;
}
var step=1;
var left,right;
while(step<arr.length){
left=0;
right=step;
while(right+step<=arr.length){
mergeArrays(arr, left, left+step, right, right+step);
left=right+step;
right=left+step;
}
if(right<arr.length){
mergeArrays(arr, left, left+step, right, arr.length);
}
step*=2;
}
}
function mergeArrays(arr, startLeft, stopLeft,startRight, stopRight){
var rightArr=new Array(stopRight - startRigh + 1);
var leftArr=new Array(stopLeft - startLeft + 1);
var k = startRight;
for(var i=0;i<(rightArr.length-1);i++){
rightArr[i]=arr[k];
++k;
}
k=startLeft;
for(var j=0;j<(leftArr.length-1);j++){
leftArr[j]=arr[k];
++k;
}
rightArr[rightArr.length-1]=Infinity;//哨兵值
leftArr[leftArr.length-1]=Infinity;//哨兵值
var m=0;
var n=0;
for(var k=startLeft;k<stopRight;k++){
if(leftArr[m]<=rightArr[n]){
arr[k]=leftArr[m];
m++;
}else{
arr[k]=rightArr[n];
n++;
}
}
console.log("left array:"+ leftArr);
console.log("right array:"+ rightArr);
}
快速排序
快速排序是处理大数据集
最快
的算法之一(处理小数据集时性能反而下降
)。他是一种分而治之的算法,通过递归的方式将数据依次分解为包含较小元素和较大元素的不同子序列。快速排序算法如下:
1、 选择一个基准元素。将列表分割成两个子序列。
2、 对列表重新排序,将所有小于基准值的元素放在基准值的前面,所有大于基准值的元素放在基准值的后面。
3、 分别对较小元素的子序列和较大元素的子序列重复步骤1和2。
function qSort(list){
if(list.length==0){
return [];
}
var lesser=[];
var greater=[];
var pivot=list[0];
for(var i=1;i<list.length;i++){
if(list[i]>pivot){
lesser.push(list[i]);
}else{
greater.push(list[i]);
}
}
//连接lesser 基准值 greater 迭代
return qSort(lesser).concat(pivot, qSort(greater));
}