云社区 博客 博客详情
云社区 博客 博客详情

野生前端的数据结构练习(10)希尔排序,归并排序,快速排序

大史不说话 发表于 2018-11-29 11:53:39 11-29 11:53
大史不说话 发表于 2018-11-29 11:53:39 2018/11/29
0
0

【摘要】 shell sort也称缩小增量排序,是对插入排序算法的改进,其工作原理是定义一个间隔序列来表示排序过程中进行比较的元素之间有多远的间隔,每次将具有相同间隔的数分为一组,进行插入排序,大部分场景中,间隔是可以提前定义好的,也可以动态生成。在较大的数据集上,希尔排序对于插排的优化效果是非常明显的。

一.希尔排序

shell sort也称缩小增量排序,是对插入排序算法的改进,其工作原理是定义一个间隔序列来表示排序过程中进行比较的元素之间有多远的间隔,每次将具有相同间隔的数分为一组,进行插入排序,大部分场景中,间隔是可以提前定义好的,也可以动态生成。在较大的数据集上,希尔排序对于插排的优化效果是非常明显的。

./**
 * 希尔排序示例代码
 */function shellSort(gaps, arr) {    for(let g = 0; g < gaps.length; g++){        let h = gaps[g];        for(let i = gaps[h]; i < arr.length ; i++){            for(let j = i; j >= h; j = j - h){                if (arr[j] < arr[j-h]) {
                    swap(arr, j, j-h);
                }
            }
        }
    }
}function swap(arr, a, b) {    let temp;
    temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
}

如果觉得算法理解起来比较抽象,可以参考下面的动图感受一下希尔排序的过程:

野生前端的数据结构练习(10)希尔排序,归并排序,快速排序

二.归并排序

merge sort的基本思想是分治法,假设我们拥有两个已经排好序的集合,规模为T(n/2),现在要将这两个集合合并为一个有序集合,合并的方法如下:

function merge(set1, set2) {    let result = [];    let p1 = 0;    let p2 = 0;    let index = p1;    while (p1 < set1.length && p2 < set2.length){        if (set1[p1] < set2[p2]) {
            result.push(set1[p1++]);
        } else {
            result.push(set2[p2++]);
        }
    }    if(p1 === set1.length){
        result = result.concat(set2.slice(p2,set2.length))
    } else {
        result = result.concat(set1.slice(p1, set1.length));
    }    return result;
}

也就是每次比较两个已排序序列的第一个元素,把较小的拿出来放进结果数组里,当一个序列中的元素全部被取出后,把另一个序列剩下的元素一次性取出加入结果数组,也就是说通过一个线性阶的算法(也就是时间复杂度为O(n))将两个排好序的集合合并了。

分治思想是指将一个问题分解为若干规模更小但本质解法相同的问题,例如上面的例子中,对一个拥有n个元素的集合排序,可以拆分为对两个n/2规模的集合排序,然后在使用上面的算法将其合并,而每个规模为n/2的问题又可以被拆分为两个规模为n/4的问题来求解,当拆分至集合中只有一个元素时,将不需要进行集合内排序,仅进行自底向上的合并即可。

归并排序的主逻辑代码如下:

function mergeSort(Arr) {    let left;    let right;    let pos;    let result;    if (Arr.length === 1) {        return Arr;
    } else {
        pos = Math.floor(Arr.length / 2);
        left = Arr.slice(0, pos);
        right = Arr.slice(pos, Arr.length);
        result = merge(mergeSort(left), mergeSort(right));        console.log('merge step:',result);        return result;
    }
}//使用数组进行测试unSortArr = [5,2,4,16,7,23,28,56,12,19];console.log(mergeSort(unSortArr));

结果如下:

野生前端的数据结构练习(10)希尔排序,归并排序,快速排序

三.快速排序

quick sort是处理大数据集最快的排序算法之一(需要注意的是在处理小数据集时排序性能反而可能下降),它也采用了分治法的思想。merge sort是先按照物理规模减半,在合并时进行排序,quick sort的基本过程是选择一个元素作为基准值pivot,然后将比它大的和比它小的分别拆分为两组,也就是说快排算法拆分得到的子序列并不一定是等规模的。快排的过程可以直观地想象为复现一棵二叉搜索树。

./**
 * 快速排序示例代码
 */function quickSort(arr) {    if (arr.length <= 1) {        return arr;
    }    let pivot = arr[0];    let left = [];    let right = [];    for(let i = 1; i < arr.length; i++){        if (arr[i] >= pivot) {
            right.push(arr[i]);
        } else {
            left.push(arr[i]);
        }
    }    return quickSort(left).concat(pivot).concat(quickSort(right));
}let arr = [72,54,58,30,31,78,2,77,82,72];console.log(quickSort(arr));


demo.rar 1.3KB 下载7

登录后可下载附件,请登录或者注册

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:huaweicloud.bbs@huawei.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
评论文章 //点赞 收藏 0
点赞
分享文章到微博
分享文章到朋友圈

评论 (0)


0/1000
评论

登录后可评论,请 登录注册

评论

您还没有写博客的权限!

温馨提示

您确认删除评论吗?

确定
取消
温馨提示

您确认删除评论吗?

删除操作无法恢复,请谨慎操作。

确定
取消
温馨提示

您确认删除博客吗?

确定
取消

确认删除

您确认删除博客吗?

确认删除

您确认删除评论吗?

温馨提示

登录超时或用户已下线,请重新登录!!!

确定
取消