JavaScript——分治算法及相关算法例题

目录

一、基本思想

二、基本步骤及适用情况

基本步骤:

适用情况:

三、常见算法使用

1、快速排序

2、归并排序


一、基本思想

分治,从字面上我们可以看出它的含义——分而治之,,它不是一个解决特定问题的算法,而是一种解决问题的思路。分治算法是有效算法设计中普遍采用的一种技术。

所谓“分而治之”就是把一个复杂的算法问题按照一定的“分解”方法分成等价的规模较小的若干部分,然后进行逐个解决,分别找出各部分的解,再把各部分的解组成整个问题的解。

也就是说,分治策略是如果一个规模为M的问题可以容易地解决则直接解决,否则将其分解成N个规模较小的子问题(N<=M),这些子问题相互独立且与原问题性质相同,那么我们只要求出子问题的解(递归解出这些子问题),然后将各个子问题的解合并就可以求出原问题的解。

二、基本步骤及适用情况

基本步骤:

适用情况:

  • 原问题的规模缩小到一定程度就可以容易地解决;
  • 若不能容易地解决原问题,判断该问题是否可以分解成若干个规模较小的相同问题;
  • 利用该问题分解出的子问题的解可以合并得到原问题的解;(关键)
  • 原问题分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。

三、常见算法使用

1、快速排序

快速排序,顾名思义,它是公认的最快的排序算法之一,有着广泛的应用。快速排序就是使用了分治算法的思想。

基本思路:

        先在数组中确定一个“支点”(或称“基准”)(pivot),将所有小于这个“支点”的值都放在该点的左侧(右侧),大于这个“支点”的值都放在该点的右侧(左侧),与“支点”相同的数可以放在任一边,然后对左右两侧不断重复这个过程,直到所有排序完成。

       支点左右侧的值根据排序规则来决定,如果从小到大排列,支点左侧就是比它小的值,右侧就是比它大的值。

时间复杂度:O(nlogn)

例:对数组[38,26,89,56,17,44]所有元素进行从小到大排序。

排序过程图如下:

代码实现:

/*以数组中间值为支点*/

function quickSort(arr,left,right){

    var len = arr.length;

    if(len<2) return arr;

    left = (typeof left !== "number" ? 0:left);

    right = (typeof right !== "number" ? len-1:right);  

    var index = Partition(arr,left,right);

    if(left < index-1){

        quickSort(arr,left,index-1);

    }

    if(index < right){

        quickSort(arr,index,right);

    }

    return arr;

}

//分区操作

function Partition(arr,left,right){

    var pivot = arr[Math.floor((left+right)/2)];   //以中间值为支点(基准点)

    var i = left;

    var j = right;

    while(i<=j){

        while(arr[i]<pivot){

            i++;

        }

        while(arr[j]>pivot){

            j--;

        }

        if(i<=j){

            var temp = arr[i];

            arr[i] = arr[j];

            arr[j] = temp;

            i++;

            j--;

        }

    }

    return i;

}

var arr = [38,26,89,56,17,44];

var left = 0;

var right = arr.length-1;

console.log("快速排序前的数组是:",arr);

arr = quickSort(arr,left,right);

console.log("快速排序后的数组是:",arr);

实现效果如下:

2、归并排序

归并排序,是建立在归并操作上的一种有效的排序算法,这是一种被广泛使用的排序方法。归并排序算法也是采用分治法的一个非常典型的应用。

基本思路:

       归并排序的思想是:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再试子序列段间有序,最终合并成一个有序表。

       采用归并方法对数组进行排序的基本方法是:将数组不断拆成两半,直到每一半只包含零个元素或一个元素为止,然后就用merge函数,将拆成两半的数组不断合并,直到合并成一整个排序完成的数组。

时间复杂度:O(nlogn)

例:对数组[38,26,89,56,17,44]所有元素进行从小到大排序。

排序过程图如下:

代码实现:

function mergeSort(arr,left,right,temp){

    if(arr.length<2){

        return arr;

    }

    var mid = Math.floor((left+right)/2);

    if(left<right){

        mergeSort(arr,left,mid,temp);

        mergeSort(arr,mid+1,right,temp);

    }

    merge(arr,left,right,temp);

    return arr;

}

//合并过程

function merge(arr,left,right,temp){

    var i = left;

    var mid = Math.floor((left+right)/2);

    var j = mid+1;

    var t = 0;

    while(i<=mid && j<=right){

        if(arr[i]<arr[j]){

            temp[t] = arr[i];

            i++;

            t++;

        }else{

            temp[t] = arr[j];

            j++;

            t++;

        }

    }

    while(i<=mid){

        temp[t] = arr[i];

        i++;

        t++;

    }

    while(j<=right){

        temp[t] = arr[j];

        j++;

        t++;

    }

    t = 0;

    var k = left;

    while(k<=right){

        arr[k] = temp[t];

        k++;

        t++;

    }

}

var arr = [38,26,89,56,17,44];

var temp = [];

var left = 0;

var right = arr.length-1;

console.log("归并排序前的数组是:",arr);

arr = mergeSort(arr,left,right,temp);

console.log("归并排序后的数组是:",arr);

实现效果如下:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值