选择排序
概念
选择排序是一种简单直观的排序算法,无论什么数据进去都是O(n2)的时间复杂度。所以用到他的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
思路
首先在未排序序列中找到最大(小)元素,存放到排序序列的其实位置 再重剩余未排序元素中继续寻找最大(小)元素,然后放到已排序序列的末尾 重复第二步,直到所有排序均排序完毕。
代码实现
function selectionSort(arr) {
//保存最小值索引
let minIndex,temp
for (let i = 0; i < arr.length - 1; i++) {
minIndex = i;
//从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([3,4,9,2,6,1,8,7,5]))
console.log(selectionSort([3,2,1]))
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
//[1, 2, 3]
插入排序
概念
插入排序是一种简单直观的排序算法,它的工作原理将序列中第一个元素作为有序序列,然后取出后续未排序的元素,在已排序序列中从后向前扫描,找到对应位置插入。
思路
用第一位元素构建有序序列,将第二个到最后一个元素作为未排序序列 扫描未排序序列,取出每一个元素在有序序列从后向前扫描,找到对应位置插入
代码实现
function insertionSort(arr) {
let preIndex, current
for (let i = 1; i < arr.length; i++) {
preIndex = i - 1
current = arr[i]
while (arr[preIndex] > current) {
arr[preIndex+1] = arr[preIndex]
preIndex--
}
arr[preIndex + 1] = current
}
return arr
}
console.log(insertionSort([3,4,9,2,6,1,8,7,5]))
console.log(insertionSort([3,2,1]))
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
//[1, 2, 3]
快速排序
概念
快速排序的基本思想是:分而治之+递归
思路
将无序序列中随机一个元素作为基点 将剩余元素小的排基点左边,大的排基点右边 基点前后两部分递归排序
代码实现
/**
* left 排序元素的起始位置
* right 排序元素的终止为止
* left(0)---right(len-1) 之间的元素进行排序
*/
function quickSort(arr, left, right) {
var partitionIndex,
len = arr.length,
left = typeof left != 'number' ? 0 : left,
right = typeof right != 'number' ? len - 1 : right;
if (left < right) {
partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1)
quickSort(arr, partitionIndex + 1, right)
}
return arr
}
//partition 隔断函数
function partition(arr, left, right) {
var pivot = left;
var index = pivot + 1;//index用来记录已经排序的下一个位置
for (var i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index)
index++
}
}
swap(arr, pivot, index - 1)
return index - 1
}
function swap(arr, i, j) {
var temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
console.log(quickSort([3, 4, 9, 2, 6, 1, 8, 7, 5]))
console.log(quickSort([3,2,1]))
//(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
//(3) [1, 2, 3]
冒泡排序
概念
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
思路
循环数组并拿出相邻两个元素比较,大的往后,小的往前,最大的元素会被推到末尾 循环上个循环(不包括最后一位),直到剩下一个元素
代码实现
function bubbleSort(arr){
var len = arr.length;
for(var i = 0; i < len - 1; i++){
for(var j = 0; j < len - 1 - i; j++){
if(arr[j]>arr[j+1]){
var temp = arr[j+1]
arr[j+1] = arr[j]
arr[j] = temp
}
}
}
}
console.log(bubbleSort([3, 4, 9, 2, 6, 1, 8, 7, 5]))
console.log(bubbleSort([3,2,1]))
//(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
//(3) [1, 2, 3]
希尔排序
概念
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。
思路
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
代码实现
function shellSort(arr) {
var len = arr.length,
gap = Math.floor(len / 2)
for (gap; gap > 0; gap = Math.floor(gap / 2)) {
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
}
console.log(shellSort([3, 4, 9, 2, 6, 1, 8, 7, 5]))
console.log(shellSort([3, 2, 1]))
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
//[1, 2, 3]
计数排序
概念
计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的做法,而且当O(k)>O(n * log(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(n * log(n)), 如归并排序,堆排序)
思路
统计原数组arr中的值为i的元素出现的次数,存在数组C的第i个位置
设置游标sortedIndex=0 再遍历数组C,只要位置c(i)不为0,则原数组arr[sortedIndex] = i,接着统计数C(i)-1,游标sortedIndex+1
代码实现
function countingSort(arr) {
var bucket = [];
var sortedIndex = 0;
for(var i = 0;i < arr.length;i++){
if(!bucket[arr[i]]){
bucket[arr[i]] = 0
}
bucket[arr[i]] ++
}
for(var i = 0;i < bucket.length;i++){
while(bucket[i]>0){
arr[sortedIndex++] = i
bucket[i]--
}
}
return arr
}
console.log(countingSort([3, 4,3,4, 9, 2, 6, 1, 8, 7, 5]))
console.log(countingSort([3, 2, 1]))
//[1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9]
//[1, 2, 3]