视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JS如何实现排序和搜索算法
2020-11-27 19:26:55 责编:小采
文档


归并排序是一种分治算法。其思想是将原始数组切分成较小的数组,直到每个小数组只有一 个位置,接着将小数组归并成较大的数组,直到最后只有一个排序完毕的大数组。因此需要用到递归

核心:归并排序,拆分成左右两块数组,分别排序后合并

动图:

注意:递归中最小的左右数组比较为单个元素的数组,因此在较上层多个元素对比时,左右两个数组一定是顺序的

代码:

function mergeSort(arr) {
 const len = arr.length;

 if (len < 2) return arr; // 递归的终止条件
 const middle = Math.floor(len / 2); // 拆分左右数组
 const left = arr.slice(0, middle);
 const right = arr.slice(middle);
 
 return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right) { // 将左右两侧比较后进行合并
 const ret = [];

 while (left.length && right.length) {
 if (left[0] > right[0]) {
 ret.push(right.shift());
 } else {
 ret.push(left.shift());
 }
 }

 while (left.length) {
 ret.push(left.shift());
 }
 while (right.length) {
 ret.push(right.shift());
 }

 return ret;
}

2.5 快速排序

快速排序也许是最常用的排序算法了。它的复杂度为O(nlogn),且它的性能通常比其他的复 杂度为O(nlogn)的排序算法要好。和归并排序一样,快速排序也使用分治的方法,将原始数组分为较小的数组

核心:分治算法,以参考值为界限,将比它小的和大的值拆开

动图:

注意:每一次遍历筛选出比基准点小的值

代码:

function quickSort(arr, left = 0, right = arr.length - 1) {
 // left和right默认为数组首尾
 if (left < right) {
 let partitionIndex = partition(arr, left, right);
 quickSort(arr, left, partitionIndex - 1);
 quickSort(arr, partitionIndex + 1, right);
 }
 return arr;
}

function partition(arr, left, right) {
 let pivot = left;
 let index = left + 1; // 满足比较条件的依次放在分割点后

 for (let i = index; i <= right; i += 1) {
 if (arr[i] < arr[pivot]) {
 swap(arr, i, index);
 index += 1;
 }
 }
 swap(arr, index - 1, pivot); // 交换顺序时,以最后一位替换分隔项
 return index - 1;
}

三、搜索算法

3.1 顺序搜索

顺序或线性搜索是最基本的搜索算法。它的机制是,将每一个数据结构中的元素和我们要找的元素做比较。顺序搜索是最低效的一种搜索算法。

function findItem(item, arr) {
 for (let i = 0; i < arr.length; i += 1) {
 if (item === arr[i]) {
 return i;
 }
 }
 return -1;
}

3.2 二分搜索

二分搜索要求被搜索的数据结构已排序。以下是该算法遵循的步骤:

  1. 选择数组的中间值
  2. 如果选中值是待搜索值,那么算法执行完毕
  3. 如果待搜索值比选中值要小,则返回步骤1在选中值左边的子数组中寻找
  4. 如果待搜索值比选中值要大,则返回步骤1在选中值右边的子数组中寻找
function binarySearch(item, arr) {
 arr = quickSort(arr); // 排序

 let low = 0;
 let high = arr.length - 1;
 let mid;

 while (low <= high) {
 min = Math.floor((low + high) / 2);
 if (arr[mid] < item) {
 low = mid + 1;
 } else if (arr[mid] > item) {
 high = mid - 1;
 } else {
 return mid;
 }
 }
 return -1;
}

四、算法复杂度

4.1 理解大O表示法

大O表示法用于描述算法的性能和复杂程度。分析算法时,时常遇到一下几类函数

(1)O(1)

function increment(num){
 return ++num;
}

执行时间和参数无关。因此说,上述函数的复杂度是O(1)(常数)

(2)O(n)

顺序搜索函数为例,查找元素需要遍历整个数组,直到找到该元素停止。函数执行的总开销取决于数组元素的个数(数组大小),而且也和搜索的值有关。但是函数复杂度取决于最坏的情况:如果数组大小是10,开销就是10;如果数组大小是1000,开销就是1000。这种函数的时间复杂度是O(n),n是(输入)数组的大小

(3)O(n2)

冒泡排序为例,在未优化的情况下,每次排序均需进行n*n次执行。时间复杂度为O(n2)

时间复杂度O(n)的代码只有一层循环,而O(n2)的代码有双层嵌套循环。如 果算法有三层遍历数组的嵌套循环,它的时间复杂度很可能就是O(n3)

4.2 时间复杂度比较

(1)常用数据结构时间复杂度

(2)排序算法时间复杂度

相关视频教程推荐:《JavaScript教程》

下载本文
显示全文
专题