JavaScript实现的十个重要算法

本文介绍了使用JavaScript实现的十大重要算法,包括快速排序、堆排序、归并排序、二分查找、BFPRT线性查找、DFS深度优先搜索、BFS广度优先搜索、Dijkstra最短路径算法、动态规划以及朴素贝叶斯分类算法。每个算法都有详细的步骤解析和代码实现。
摘要由CSDN通过智能技术生成

注:本文的文字解释部分并非原创,我只是对其实现用JavaScript代码来实现,以供大家学习和参考。如有错误还请不吝指出。

原文地址:程序员必须知道的10大基础实用算法及其讲解

算法一:快速排序算法

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。


快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:


1 从数列中挑出一个元素,称为 “基准”(pivot),

2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。


递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

代码实现:
function quickSort (arr) {
   
            if(arr.length <= 1){
                return arr;
            }
            // 选择基准,并将其与原数组分离,在定义两个空数组,用来存放一左一右两个子集
            var pivotIndex = Math.floor(arr.length/2);
            var pivot = arr.splice(pivotIndex,1)[0]; 
            var left = [];
            var right = [];
            // 然后开始遍历数组,将小于基准的元素放入左边,大于基准的放入右边
            for(var i = 0;i < arr.length; i++){
                if (arr[i] < pivot) {
                    left.push(arr[i]);
                } else{
                    right.push(arr[i]);
                }
                // console.log(arr);
            }
            // 最后,使用递归不断重复这个过程
            return quickSort(left).concat([pivot],quickSort(right));
        }

        console.log(quickSort([3,3,4,15,331,348,98,12]));


程序员必须知道的10大基础实用算法及其讲解 - 第1张  | 快课网

详细介绍: 快速排序

算法二:堆排序算法


堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。


堆排序的平均时间复杂度为Ο(nlogn) 。

算法步骤:


1.创建一个堆H[0..n-1]
2.把堆首(最大值)和堆尾互换
3. 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置
4. 重复步骤2,直到堆的尺寸为1
代码:
// 堆排序  
    var h = [],// 用来存放堆的数组  
        n;// 用来存储堆中元素的个数,也就是堆的大小  
    // 交换函数,交换堆中两个元素的值  
    function swap(x,y){
     
        var t;  
        t = h[x];  
        h[x] = h[y];  
        h[y] = t;  
    }  
    // 向下调整函数  
    function siftdown(i){
     
        // 传入一个需要向下调整的节点编号i,这里传入1,即从堆的定点开始向下调整  
        var flag = 0,// flag用来标记是否需要继续向下调整  
            t;  
        // 当i节点有儿子(其实至少有左儿子)并且需要继续调整的时候循环就执行  
        while(i*2 <= n && flag === 0){  
            // 首先判断它和左儿子的关系,并用t记录值较小的节点编号  
            var leftChildIndex = i*2+1,  
                rightChildIndex = i*2+2;  
            if(h[i] > h[leftChildIndex]){  
                t = leftChildIndex;  
            }else{  
                t = i;  
            }  
            // 如果它有右儿子,在对右儿子进行讨论  
            if(right
  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值