注:基数排序中:r是关键字的基数,d是长度,n是关键字的个数

1.插入排序
基本思想:在序号i之前的元素(0到i-1)已经排好序,本趟需要找到i对应的元素x (此时即arr[i]) 的正确位置k,在寻找位置k的过程中与序号i-1到0的元素依次进行比较。如果x小于比较元素,则比较元素向后移动一位;否则,结束移位,将x插入当前位置k
 function insertSort(arr) {
for (let i = 1; i < arr.length; i++) {
// 将待插入元素提取出来
let temp = arr[i]
let j
for (j = i - 1; j >= 0; j--) {
if (arr[j] > temp) {
// 插入元素小于比较元素,比较元素则向后移动一位
arr[j + 1] = arr[j]
} else {
// 否则,结束移位
break
}
}
//将插入元素插入正确位置
arr[j + 1] = temp
}
return arr
}
console.log(insertSort([7, 3, 4, 5, 10, 7, 8, 2]))
 
1.1插入排序的优化二分排序
与插入排序思想差不多,但是二分排序是在插入第i个元素时,对前面的0~i-1元素进行折半,先跟它们中间的元素进行比较。如果小,那么对前半进行折半;如果打,那么对后半进行折半。依次进行,直到left>right。然后再把第i个元素前一位与目标位置之间的所有元素向后移动一位,再将目标元素放入正确位置上。
 function binarySort(arr) {
for (let i = 0; i < arr.length; i++) {
let temp = arr[i]
let left = 0
let right = i - 1
let mid
while (left <= right) {
mid = Math.floor((left + right) / 2)
if (arr[mid] > temp) {
right = mid - 1
} else {
left = mid + 1
}
}
for (let j = i - 1; j >= left; j--) {
arr[j + 1] = arr[j]
}
if (left !== i) {
arr[left] = temp
}
}
return arr
}
console.log(binarySort([7, 3, 4, 5, 10, 7, 8, 2]))
2.希尔排序
基本思想:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
 function shellSort(arr) {
let d = arr.length
while (true) {
d = Math.floor(d / 2)
for (let x = 0; x < d; x++) {
for (let i = x + d; i < arr.length; i = i + d) {
let temp = arr[i]
let j
for (j = i - d; j >= 0 && arr[j] > temp; j = j - d) {
arr[j + d] = arr[j]
}
arr[j + d] = temp
}
}
if (d == 1) {
break
}
}
return arr
}
console.log(shellSort([7, 3, 4, 5, 10, 7, 8, 2]))
3.直接选择排序
基本思想:每次选择待排序的元素中最小的值,放置在序列的首位
 function directSelectSort(arr) {
for (let i = 0; i < arr.length; i++) {
let min = arr[i]
let index = i
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < min) {
// 找到最小值,并标注最小值索引,方便后续与元素arr[i]交换位置
min = arr[j]
index = j
}
}
arr[index] = arr[i]
arr[i] = min
}
return arr
}
console.log(directSelectSort([7, 3, 4, 5, 10, 7, 8, 2]))
4.堆排序
堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单
用大根堆排序的基本思想
① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key
③由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。……
直到无序区只有一个元素为止。
 let len

 function buildMaxHeap(arr) {
//建立大根堆
len = arr.length
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i)
}
} function heapify(arr, i) {
//堆调整
let left = 2 * i + 1,
right = 2 * i + 2,
largest = i if (left < len && arr[left] > arr[largest]) {
largest = left
} if (right < len && arr[right] > arr[largest]) {
largest = right
} if (largest !== i) {
// 解构赋值,交换变量
;[arr[i], arr[largest]] = [arr[largest], arr[i]]
heapify(arr, largest)
}
} function heapSort(arr) {
buildMaxHeap(arr) for (let i = arr.length - 1; i > 0; i--) {
;[arr[0], arr[i]] = [arr[i], arr[0]]
len--
heapify(arr, 0)
}
return arr
} console.log(heapSort([7, 3, 4, 5, 10, 7, 8, 2]))
5.冒泡排序
基本思想:每次比较两相邻的数,当发现它们的排序与排序要求相反时,就将它们互换。这样小的数往下沉,大的数往上冒
 function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
// 因为每次比较时都已经有i个元素沉下去了,所以j<arr.length-1-i
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// 这里采用了解构赋值。如果一般做法,借助临时变量,则辅助空间是O(1)
;[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
}
}
}
return arr
}
console.log(bubbleSort([7, 3, 4, 5, 10, 7, 8, 2]))
6.快速排序
基本思想:选择一个基准元素(通常选择第一个元素),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有元素都比基准元素小,另外一部分的所有元素大于或等于基准元素大。同样方法依次分割;整个排序过程可以递归进行。
 let quicksort = function(arr) {
if(arr.length <= 1) return arr; let pivot = Math.floor((arr.length -1)/2);
let val = arr[pivot], less = [], more = []; arr.splice(pivot, 1);
arr.forEach(function(e,i,a){
e < val ? less.push(e) : more.push(e);
}); return (quicksort(less)).concat([val],quicksort(more))
}
console.log(quicksort([7, 3, 4, 5, 10, 7, 8, 2]))
7.归并排序
基本思想:将待排序序列分为若干个子序列,每个子序列是有序的,然后将有序子序列合并为整体有序序列。
 function merge(left, right) {
let result = []
while (left.length > 0 && right.length > 0) {
if (left[0] < right[0]) {
/*shift()方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。*/
result.push(left.shift())
} else {
result.push(right.shift())
}
}
return result.concat(left).concat(right)
}
function mergeSort(arr) {
if (arr.length == 1) {
return arr
}
let middle = Math.floor(arr.length / 2),
left = arr.slice(0, middle),
right = arr.slice(middle)
return merge(mergeSort(left), mergeSort(right))
}
console.log(mergeSort([7, 3, 4, 5, 10, 7, 8, 2]))
8.基数排序
基本思想:将所有待比较元素(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从个位开始,进行排序;然后十位,进行排序;以此进行!这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
基数排序两种方法:
MSD 从高位开始进行排序
LSD 从低位开始进行排序
 // LSD Radix Sort
// helper function to get the last nth digit of a number
var getDigit = function(num,nth){
// get last nth digit of a number
var ret = 0;
while(nth--){
ret = num % 10
num = Math.floor((num - ret) / 10)
}
return ret
} // radixSort
function radixSort(arr){
var max = Math.floor(Math.log10(Math.max.apply(Math,arr))),
// get the length of digits of the max value in this array
digitBuckets = [],
idx = 0; for(var i = 0;i<max+1;i++){ // rebuild the digit buckets according to this digit
digitBuckets = []
for(var j = 0;j<arr.length;j++){
var digit = getDigit(arr[j],i+1); digitBuckets[digit] = digitBuckets[digit] || [];
digitBuckets[digit].push(arr[j]);
} // rebuild the arr according to this digit
idx = 0
for(var t = 0; t< digitBuckets.length;t++){
if(digitBuckets[t] && digitBuckets[t].length > 0){
for(j = 0;j<digitBuckets[t].length;j++){
arr[idx++] = digitBuckets[t][j];
}
}
}
}
return arr
}
console.log(radixSort([7, 3, 4, 5, 10, 7, 8, 2]))

注:网上有很多javascript实现的基数排序代码时错误的

当搜索一些问题时,尽量使用英文进行搜索!

JavaScript实现八大内部排序算法的更多相关文章

  1. Java实现各种内部排序算法

    数据结构中常见的内部排序算法: 插入排序:直接插入排序.折半插入排序.希尔排序 交换排序:冒泡排序.快速排序 选择排序:简单选择排序.堆排序 归并排序.基数排序.计数排序 直接插入排序: 思想:每次将 ...

  2. 常见内部排序算法对比分析及C++ 实现代码

    内部排序是指在排序期间数据元素全部存放在内存的排序.外部排序是指在排序期间全部元素的个数过多,不能同时存放在内存,必须根据排序过程的要求,不断在内存和外存之间移动的排序.本次主要介绍常见的内部排序算法 ...

  3. 用 Java 实现常见的 8 种内部排序算法

    一.插入类排序 插入类排序就是在一个有序的序列中,插入一个新的关键字.从而达到新的有序序列.插入排序一般有直接插入排序.折半插入排序和希尔排序. 1. 插入排序 1.1 直接插入排序 /** * 直接 ...

  4. JavaScript实现常用的排序算法

    ▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排 ...

  5. 七内部排序算法汇总(插入排序、Shell排序、冒泡排序、请选择类别、、高速分拣合并排序、堆排序)

    写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的随意序列,又一次排列成一个按keyword有序的序列.因此排序掌握各种排序算法很重要. 对以下介绍的各个排序,我们假定全部排 ...

  6. JavaScript十大经典排序算法

    排序算法说明 (1)排序的定义:对一序列对象根据某个关键字进行排序: 输入:n个数:a1,a2,a3,…,an输出:n个数的排列:a1’,a2’,a3’,…,an’,使得a1’ 再讲的形象点就是排排坐 ...

  7. JavaScript的9大排序算法详解

    一.插入排序 1.算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. ...

  8. 必须知道的八大种排序算法【java实现】(二) 选择排序,插入排序,希尔算法【详解】

    一.选择排序 1.基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换:然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止. 2.实例 3.算法 ...

  9. 必须知道的八大种排序算法【java实现】(一) 冒泡排序、快速排序

    冒泡排序 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个 ...

随机推荐

  1. 《天书夜读:从汇编语言到windows内核编程》五 WDM驱动开发环境搭建

    (原书)所有内核空间共享,DriverEntery是内核程序入口,在内核程序被加载时,这个函数被调用,加载入的进程为system进程,xp下它的pid是4.内核程序的编写有一定的规则: 不能调用win ...

  2. 人生苦短,python是岸.

    人生苦短,python是岸. 愿付一生,应许之诚.

  3. Cordic算法——verilog实现

    上两篇博文Cordic算法--圆周系统之旋转模式.Cordic算法--圆周系统之向量模式做了理论分析和实现,但是所用到的变量依然是浮点型,而cordic真正的用处是基于FPGA等只能处理定点的平台.只 ...

  4. IIS发布网站浏览之后看到的是文件目录 & Internal Server Error 处理程序“ExtensionlessUrlHandler-ISAPI-4.0_64bit”在其模块列表中有一个错误模块“IsapiModule” 解决方法 & App_global.asax.pduxejp_.dll”--“拒绝访问。 ”

    Q:IIS发布网站浏览之后看到的是文件目录 A:它出现了一个说到.NET4.0 更高框架什么的错误,所以我将 .NTE CRL版本由4.0改为2.0了,改为2.0后就出现了只能浏览文件目录了.改为4. ...

  5. 《Metasploit魔鬼训练营》第三章

    p85 使用nmap探测目标主机的操作系统版本那里有问题,我探测不了NAT服务器的! msf > nmap -sT 10.10.10.254 [*] exec: nmap -sT 10.10.1 ...

  6. 高性能分布式执行框架——Ray

    Ray是UC Berkeley AMP实验室新推出的高性能分布式执行框架,它使用了和传统分布式计算系统不一样的架构和对分布式计算的抽象方式,具有比Spark更优异的计算性能. Ray目前还处于实验室阶 ...

  7. 1455:An Easy Problem

    传送门:http://noi.openjudge.cn/ch0406/1455/ /-24作业 //#include "stdafx.h" #include<bits/std ...

  8. hadoop2.5的伪分布式安装配置

    一.windows环境下安装 根据博主写的一次性安装成功了: http://blog.csdn.net/antgan/article/details/52067441 二.linux环境下(cento ...

  9. Less变量

    Less变量 定义变量 Less 中的变量和其他编程语言一样,可以实现值的复用,同样它也有作用域(scope).简单的讲,变量作用域就是局部变量和全局变量的概念. Less 中,变量作用域采用的是就近 ...

  10. VMWare安装Win10虚拟机

    这两天突发奇想安了个win10虚拟机,在安装的过程中还遇到了不少麻烦,所以在此与大家分享下. 首先我们用VMWare12来安装,VMWare已经更新到14但是不太稳定,所以为了保险起见还是用12吧. ...