摘要:最差情况输入数组按降序排列。平均情况稳定性稳定希尔排序排序法是对相邻指定距离称为增量的元素进行比较,并不断把增量缩小至,完成排序。若将两个有序表合并成一个有序表,称为二路归并。
冒泡排序
从数组中第一个数开始,依次遍历数组中的每一个数,通过相邻比较交换,每一轮循环下来找出剩余未排序数的中的最大数并”冒泡”至数列的顶端。
function bubbleSort(arr) { for (var i = 0; i < arr.length - 1 ; i++) { for (var j = 0; j < arr.length - i - 1 ; j++) { if (arr[j] > arr[j+1]) { //相邻元素两两对比 let temp = arr[j+1]; //元素交换 arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; } console.log(bubbleSort([72,54,58,30,31,78,2,77,82,72]))
最佳情况:输入数组按升序排列。 T(n) = O(n)
最差情况:输入数组按降序排列。 T(n) = O(n2)
平均情况:T(n) = O(n2)
稳定性:稳定
选择排序
从所有记录中选出最小的一个数据元素与第一个位置的记录交换;然后在剩下的记录当中再找最小的与第二个位置的记录交换,循环到只剩下最后一个数据元素为止。
function selectionSort(arr) { let minIndex,temp; for (let i = 0; i < arr.length-1; i++) { minIndex = i; for (let j = i+1; j < arr.length; j++) { if(arr[j] < arr[minIndex]) { minIndex = j; } } temp = arr[i]; arr[i]=arr[minIndex]; arr[minIndex]=temp; } return arr; } console.log(selectionSort([72,54,58,30,31,78,2,77,82,72]))
最佳情况:T(n) = O(n2)
最差情况:T(n) = O(n2)
平均情况:T(n) = O(n2)
稳定性:不稳定
插入排序
从待排序的n个记录中的第二个记录开始,依次与前面的记录比较并寻找插入的位置,每次外循环结束后,将当前的数插入到合适的位置。
function insertionSort(arr) { for (let i = 1; i < arr.length; i++) { let key = arr[i]; let j = i - 1; while (j>=0 && arr[j] > key) { arr[j+1] = arr[j]; j--; } arr[j+1] = key; } return arr; } console.log(insertionSort([6,10,0,6,5,8,7,4,2,7]))
最佳情况:输入数组按升序排列。T(n) = O(n)
最坏情况:输入数组按降序排列。T(n) = O(n2)
平均情况:T(n) = O(n2)
稳定性:稳定
希尔排序
Shell排序法是对相邻指定距离(称为增量)的元素进行比较,并不断把增量缩小至1,完成排序。
function shellSort(arr) { var len = arr.length, temp, gap = 1; while(gap < len/5) { //动态定义间隔序列 gap =gap*5+1; } for (gap; gap > 0; gap = Math.floor(gap/5)) { for (var i = gap; i < len; i++) { temp = arr[i]; for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) { arr[j+gap] = arr[j]; } arr[j+gap] = temp; } } return arr; } var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]; console.log(shellSort(arr));
最佳情况:T(n) = O(nlog2 n)
最坏情况:T(n) = O(nlog2 n)
平均情况:T(n) =O(nlog n)
稳定性:不稳定
归并排序
归并排序是分治法(Divide and Conquer)的一个典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
function mergeSort(arr) { if(arr.length < 2) { return arr; } let middle = Math.floor(arr.length/2); let left = arr.slice(0,middle); let right = arr.slice(middle); return merge(mergeSort(left),mergeSort(right)); } function merge(left,right) { let res = []; while(left.length && right.length) { if(left[0] <= right[0]) { res.push(left.shift()); } else { res.push(right.shift()); } } while(left.length) { res.push(left.shift()); } while(right.length) { res.push(right.shift()); } return res; } let arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]; console.log(mergeSort(arr));
最佳情况:T(n) = O(n)
最差情况:T(n) = O(nlogn)
平均情况:T(n) = O(nlogn)
稳定性:稳定
快速排序
1.从待排序的n个记录中任意选取一个记录(通常选取第一个记录)为分区标准;
2.把所有小于该排序列的记录移动到左边,把所有大于该排序码的记录移动到右边,中间放所选记录,称之为第一趟排序;
3.然后对前后两个子序列分别重复上述过程,直到所有记录都排好序。
方法一:
function quickSort(arr,left,right) { let i = left; let j = right; let temp = 0; if(i < j) { //待排序的元素至少有两个的情况 temp = arr[i]; //待排序的第一个元素作为基准元素 while(i != j) { //从左右两边交替扫描,直到i = j while(j > i && arr[j] >= temp) { j --; //从右往左扫描,找到第一个比基准元素小的元素 } arr[i] = arr[j]; //找到这种元素arr[j]后与arr[i]交换 while(i < j && arr[i] <= temp) { i ++; //从左往右扫描,找到第一个比基准元素大的元素 } arr[j] = arr[i]; //找到这种元素arr[i]后,与arr[j]交换 } arr[i] = temp; //基准元素归位 quickSort(arr,left,i-1); //对基准元素左边的元素进行递归排序 quickSort(arr,i+1,right); //对基准元素右边的进行递归排序 } return arr; } let arr = [5,7,1,8,4] console.log(quickSort(arr,0,arr.length-1));
方法二:
function quickSort(arr) { if(arr.length <= 1) { return arr; } let middleIndex = Math.floor(arr.length/2); let middle = arr.splice(middleIndex,1)[0];//选取基准值 并从数组中删除 let left = []; //小于middle的数组 let right = []; //大于middle的数组 for (var i = 0; i < arr.length; i++) { if(arr[i] < middle) { left.push(arr[i]); } else { right.push(arr[i]); } } return quickSort(left).concat([middle],quickSort(right)); } let arr = [5,7,1,8,4] console.log(quickSort(arr));
最佳情况:T(n) = O(nlogn)
最差情况:T(n) = O(n2)
平均情况:T(n) = O(nlogn)
稳定性:不稳定
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/107480.html
摘要:之所以把冒泡排序选择排序插入排序放在一起比较,是因为它们的平均时间复杂度都为。其中,冒泡排序就是原地排序算法。所以冒泡排序是稳定的排序算法。选择排序思路选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 1. 前言 算法为王。 想学好前端,先练好内功,...
摘要:笔者写的数据结构与算法之美系列用的语言是,旨在入门数据结构与算法和方便以后复习。这应该是目前较为简单的十大经典排序算法的文章讲解了吧。比如原本在的前面,而,排序之后,在的后面十大经典排序算法冒泡排序思想冒泡排序只会操作相邻的两个数据。 showImg(https://segmentfault.com/img/bVbvHet); 1. 前言 算法为王。想学好前端,先练好内功,内功不行,就...
摘要:稳定与不稳定算法示例以下图片解释了稳定和不稳定的排序是如何工作的这就是稳定和不稳定排序算法之间的区别。稳定排序算法的一些常见示例是合并排序,插入排序和冒泡排序。 showImg(https://segmentfault.com/img/remote/1460000018913243); 来源 | 愿码(ChainDesk.CN)内容编辑 愿码Slogan | 连接每个程序员的故事 网...
摘要:之所以把归并排序快速排序希尔排序堆排序放在一起比较,是因为它们的平均时间复杂度都为。归并排序是一种稳定的排序方法。因此,快速排序并不稳定。希尔排序思想先将整个待排序的记录序列分割成为若干子序列。 showImg(https://segmentfault.com/img/bVbvpYZ?w=900&h=250); 1. 前言 算法为王。 想学好前端,先练好内功,只有内功深厚者,前端之路才...
摘要:之所以把计数排序桶排序基数排序放在一起比较,是因为它们的平均时间复杂度都为。动画计数排序思想找出待排序的数组中最大和最小的元素。桶排序计数排序能派上用场吗手机号码有位,范围太大,显然不适合用这两种排序算法。 showImg(https://segmentfault.com/img/bVbuF9e?w=900&h=500); 1. 前言 算法为王。 想学好前端,先练好内功,只有内功深厚者...
摘要:上一篇数据结构与算法树写在前面这是学习数据结构与算法的最后一篇博客,也是在面试中常常会被问到的一部分内容排序和搜索。 上一篇:JS数据结构与算法_树 写在前面 这是《学习JavaScript数据结构与算法》的最后一篇博客,也是在面试中常常会被问到的一部分内容:排序和搜索。在这篇博客之前,我每每看到排序头就是大的,心里想着类似冒泡排序,两层遍历啪啪啪就完事了,然后再也无心去深入研究排序相...
阅读 2308·2021-08-26 14:14
阅读 2675·2019-08-29 13:07
阅读 2083·2019-08-26 11:44
阅读 675·2019-08-26 10:11
阅读 2409·2019-08-23 15:43
阅读 3076·2019-08-23 14:17
阅读 384·2019-08-23 12:36
阅读 2082·2019-08-22 15:20