算法介绍:javascript
function bubble_sort(arr){
var swap;
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]){
swap=arr[j];
arr[j]=arr[j+1];
arr[j+1]=swap;
}
}
}
}
复制代码
冒泡算法改进:html
function bubble_sort_1(arr) {
var n = arr.length,
flag = true,
swap;
while(flag){
flag = false;
for(var j = 1; j<n; j++){
if(arr[j - 1]>arr[j]) {
swap = arr[j-1];
arr[j-1] = arr[j];
arr[j] = swap;
flag = true;
}0
}
n --;
}
return arr;
}
复制代码
function bubble_sort_2(arr) {
var n=arr.length;
var j,k;
var flag=n;
var swap;
while(flag>0) {
k=flag;
flag=0;
for(j=1;j<k;j++){
if (arr[j - 1] > arr[j])
{
swap=arr[j-1];
arr[j-1]=arr[j];
arr[j]=swap;
flag=j;
}
}
}
}
复制代码
function bubble_sort_3(arr) {  
var low = 0;
var high = arr.length - 1; //设置变量的初始值
var swap, j;
while (low < high) {
for (j = low; j < high; ++j) { //正向冒泡,找到最大者
if (arr[j] > arr[j + 1]) {
swap = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = swap;
}
}    --high; //修改high值, 前移一位
for (j = high; j > low; --j) { //反向冒泡,找到最小者
if (arr[j] < arr[j - 1]) {
swap = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = swap;
}
}
++low; //修改low值,后移一位
}
return arr;
}
复制代码
function bubble_sort_3(arr) {  
var low = 0;
var high = arr.length - 1; //设置变量的初始值
var swap, j;
while (low < high) {
var pos1 = 0,
pos2 = 0;
for (let i = low; i < high; ++i) { //正向冒泡,找到最大者
if (arr[i] > arr[i + 1]) {
swap = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = swap;
pos1 = i;
}
}
high = pos1; // 记录上次位置
for (let j = high; j > low; --j) { //反向冒泡,找到最小者
if (arr[j] < arr[j - 1]) {
swap = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = swap;
pos2 = j;
}
}
low = pos2; //修改low值
}
return arr;
}
复制代码
冒泡排序动图演示:java
算法介绍:git
快速排序是对冒泡排序的一种改进,第一趟排序时将数据分红两部分,一部分比另外一部分的全部数据都要小。而后递归调用,在两边都实行快速排序。算法
function quick_sort(arr){
if(arr.length<=1){
return arr;
}
var pivotIndex=Math.floor(arr.length/2);
var pivot=arr.splice(pivotIndex,1)[0];
var left=[];
var right=[];
for(var i=0;i<arr.length;i++){
if(arr[i]<pivot){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
}
return quick_sort(left).concat([pivot],quick_sort(right));
}
复制代码
快速排序动图演示: shell
算法介绍:api
选择排序就是从一个未知数据空间里,选取之最放到一个新的空间数组
代码以下:函数
function selection_sort(arr) {
var len = arr.length;
var minIndex, swap;
for (var i = 0; i < len - 1; i++) {
minIndex = i;
for (var j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) { //寻找最小的数
minIndex = j; //将最小数的索引保存
}
}
swap = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = swap;
}
return arr;
}
复制代码
选择排序动图演示: 性能
算法介绍:
代码以下:
function insertion_sort(arr) {
for (var i = 1; i < arr.length; i++) {
var key = arr[i];
var j = i - 1;
while (arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
return arr;
}
复制代码
插入排序算法改进-二分法插入排序:
function binaryInsertion_sort(arr) {
for (var i = 1; i < arr.length; i++) {
var key = arr[i],
left = 0,
right = i - 1;
while (left <= right) {
var middle = parseInt((left + right) / 2);
if (key < arr[middle]) {
right = middle - 1;
} else {
left = middle + 1;
}
}
for (var j = i - 1; j >= left; j--) {
arr[j + 1] = arr[j];
}
arr[left] = key;
}
return arr;
}
复制代码
插入排序法动图演示:
算法介绍:
希尔排序是冒泡排序的一种更高效率的实现。它与冒泡排序的不一样之处在于,它会优先比较距离较远的元素。希尔排序的核心在于间隔序列的设定。
上图中先每差5为一组进行比较,以后再每差2为一组惊醒比较,最后就是两两比较。代码以下:
function shell_sort(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;
}
复制代码
算法介绍:
做为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
代码以下:
function merge_sort(arr) { //采用自上而下的递归方法
var len = arr.length;
if(len < 2) {
return arr;
}
var middle = Math.floor(len / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
var result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length)
result.push(left.shift());
while (right.length)
result.push(right.shift());
return result;
}
复制代码
归并排序动图演示 :
首先明白什么是堆,堆其实能够这么理解,相似金字塔,一层有一个元素,两层有两个元素,三层有四个元素,每层从数组中取元素,从左到右的顺序放到堆相应的位置上,也就是说每一层元素个数为2n-1 ;(n 表明行数),这就完成了建堆。
堆排序能够说是一种利用堆的概念来排序的选择排序。分为两种方法:
代码以下:
var len; //由于声明的多个函数都须要数据长度,因此把len设置成为全局变量
function buildMaxHeap(arr) { //创建大顶堆
len = arr.length;
for (var i = Math.floor(len/2); i >= 0; i--) {
heapify(arr, i);
}
}
function heapify(arr, i) { //堆调整
var 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) {
swap(arr, i, largest);
heapify(arr, largest);
}
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function heapSort(arr) {
buildMaxHeap(arr);
for (var i = arr.length-1; i > 0; i--) {
swap(arr, 0, i);
len--;
heapify(arr, 0);
}
return arr;
}
复制代码
堆排序动图演示:
算法介绍:
计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 做为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有肯定范围的整数。
代码以下:
function counting_sort(arr, maxValue) {
var bucket = new Array(maxValue+1),
sortedIndex = 0;
arrLen = arr.length,
bucketLen = maxValue + 1;
for (var i = 0; i < arrLen; i++) {
if (!bucket[arr[i]]) {
bucket[arr[i]] = 0;
}
bucket[arr[i]]++;
}
for (var j = 0; j < bucketLen; j++) {
while(bucket[j] > 0) {
arr[sortedIndex++] = j;
bucket[j]--;
}
}
return arr;
}
复制代码
计数排序动图演示:
桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的肯定。 为了使桶排序更加高效,咱们须要作到这两点:
在额外空间充足的状况下,尽可能增大桶的数量 使用的映射函数可以将输入的N个数据均匀的分配到K个桶中 同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响相当重要。 何时最快(Best Cases):
代码演示:
function bucketSort(arr, bucketSize) {
if (arr.length === 0) {
return arr;
}
var i;
var minValue = arr[0];
var maxValue = arr[0];
for (i = 1; i < arr.length; i++) {
if (arr[i] < minValue) {
minValue = arr[i]; //输入数据的最小值
} else if (arr[i] > maxValue) {
maxValue = arr[i]; //输入数据的最大值
}
}
//桶的初始化
var DEFAULT_BUCKET_SIZE = 5; //设置桶的默认数量为5
bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;
var bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;
var buckets = new Array(bucketCount);
for (i = 0; i < buckets.length; i++) {
buckets[i] = [];
}
//利用映射函数将数据分配到各个桶中
for (i = 0; i < arr.length; i++) {
buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);
}
arr.length = 0;
for (i = 0; i < buckets.length; i++) {
insertionSort(buckets[i]); //对每一个桶进行排序,这里使用了插入排序
for (var j = 0; j < buckets[i].length; j++) {
arr.push(buckets[i][j]);
}
}
return arr;
}
复制代码
基数排序须知:
基数排序有两种方法:
基数排序 vs 计数排序 vs 桶排序:
这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差别:
代码演示:
function radix_sort(arr, maxDigit) {
var mod = 10;
var dev = 1;
var counter = [];
for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
for (var j = 0; j < arr.length; j++) {
var bucket = parseInt((arr[j] % mod) / dev);
if (counter[bucket] == null) {
counter[bucket] = [];
}
counter[bucket].push(arr[j]);
}
var pos = 0;
for (var j = 0; j < counter.length; j++) {
var value = null;
if (counter[j] != null) {
while ((value = counter[j].shift()) != null) {
arr[pos++] = value;
}
}
}
}
return arr;
}
复制代码
基数排序动图演示: