From 3c4d1094883d7eb57baa5d706db79a6ae3e02a60 Mon Sep 17 00:00:00 2001 From: wschool Date: Wed, 16 Dec 2015 16:03:01 +0800 Subject: [PATCH] update the js_arrAlgorithm.md&complete update&complete --- js_arrAlgortithm.md | 94 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/js_arrAlgortithm.md b/js_arrAlgortithm.md index ec4e851..20bfbe5 100644 --- a/js_arrAlgortithm.md +++ b/js_arrAlgortithm.md @@ -38,6 +38,8 @@ apply有两个参数,第一个参数为执行环境,一个以数组形式传 ###桶排序 +> 将数组分到有限数量的桶里,数组项值对应桶的编号,桶里的值则是其编号对应相等的数组项值出现的次数,然后,根据桶里的值将桶的编号依次输出。 + 试想一下,你们五个小伙伴考试微积分,分别考了5分,6分,3分,8分,6分,接下来按分数高低进行排名。 如何实现呢? 这里我们只需要一个数组就能轻易解决: @@ -111,3 +113,95 @@ apply有两个参数,第一个参数为执行环境,一个以数组形式传 如代码所示,冒泡排序算法只有一个双重嵌套循环,共循环n*n次,其时间复杂度即为O(N^2)。 +###快速排序 + +快速排序,可谓最常用的排序算法,也是目前提到的平均时间复杂度最快的算法,先来了解一下: + +> 找一个基准数,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比基准数要小,另一部分的所有数据都比基准数要大,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 + +- **基准数** 一个参照数,用来将待排序数列分割成两部分。 +- **哨兵** 勘探待排序数组值依次与基准数进行比较的标记,以找到合格数(分别大于和小于基准数的两个数)。 +- **趟** 一趟排序找一个基准数,然后选取从左至右与从右至左同时进行勘探。 + +*一般基准数我们取数组第一位数。两个哨兵分别为待排序数组首尾项。* + +直接上代码: + +``` + + function quickSort(arr) { + function _sort(left, right) { + var _left = left, _right = right; + var temp; + if (left > right) { + return; + } + temp = arr[left]; + while (left != right) { + //从右往左查找 + while (arr[right] >= temp && left < right) {//如果哨兵标记的数大于等于基准数则继续‘向前’,标记下一个数 + right--; + } + //从左往右查找 + while (arr[left] <= temp && left < right) {//如果哨兵标记的数小于等于基准数则继续‘向前’,标记下一个数 + left ++; + } + //交换两个数位置 + if (left < right) {//两个哨兵均已找到目标数,如果两个哨兵未相遇,则交换当前两个哨兵所指向的目标数 + temp = arr[left]; + arr[left] = arr[right]; + arr[right] = temp; + } + } + //将此趟基准数交换至正确位置(小于基准数的数列与大于基准数的数列之间) + temp = arr[_left]; + arr[_left] = arr[left]; + arr[left] = temp; + _sort(_left, left - 1);//对分割后的两部分数列递归 + _sort(left + 1, _right); + } + _sort(0, arr.length - 1);//开始快排 + console.log(arr); + return arr; + } +``` + +- **时间复杂度平均O(NlogN)** + +如代码示,最坏情况发生时,每次划分过程产生的两个数列分别包含n-1个元素和1个元素,此时相当于有两层嵌套循环,时间复杂度为O(N^2),与冒泡排序一致,而最好情况下,每次划分产生的两个数列长度大致相等,时间复杂度为O(NlogN)。 + +**尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。** + +##JavaScript数组去重 + +关于数组去重,也有很多种方法,在此给出几种效率最高的,借鉴一二。 + +``` + + /** 第一种 */ + function uniqueArray(arr) { + var res = [arr[0]]; + for(var i = 1; i < arr.length; i++) //从第二项开始遍历 + { + //若数组第i项在当前数组中下标不是i,则说明第i项重复,应忽略。否则存入结果数组 + if (arr.indexOf(arr[i]) == i) { + res.push(arr[i]); + } + } + return res; + } + + /** 第二种 */ + function uniqueArray(arr) { + var _hash = {}, result = []; + for (var i = 0; i < arr.length; i++) { + if (!_hash[arr[i]]) { + _hash[arr[i]] = true; //将首次遍历到的数组项存入hash对象,效率比indexOf快得多 + result.push(arr[i]); + } + } + return result; + } +``` + +总结:此篇虽篇幅略长,但细细读来,想来还是能有些收获,足矣。 \ No newline at end of file