摘要
通过JavaScript实现的排序算法
数组构造
基本数组函数及方法构造
function ArrayList() {
//属性
this.items = [],
//插入数据
ArrayList.prototype.insert = function(data) {
this.items.push(data);
}
//打印数组
ArrayList.prototype.toString = function() {
console.log(this.items.join("-"));
}
//交换函数
ArrayList.prototype.swap = function(i, j) {
var temp = this.items[i];
this.items[i] = this.items[j];
this.items[j] = temp;
}
}
一、简单排序
1.冒泡排序
代码及详解:
图解:
//排序算法
//1.冒泡排序(时间复杂度O(n^2))
ArrayList.prototype.bubbleSort = function() {
//原理分析:重复从头开始两两比较,将大的值置后,每次比较次数随着每次选出的最大值个数减少
//第1次 i = 0 ,两两比较,需要比较到 i = length-2
//第2次 i = 0 ,两两比较,需要比较到 i = length-3
//第3次 i = 0 ,两两比较,需要比较到 i = length-4
//第n次 i = 0 ,两两比较,需要比较到 i = length-n-1
//最后一次 i = 0 ,两两比较,需要比较到 i = 1 > 0
for (var j = this.items.length - 1; j > 0; j--) {
for (var i = 0; i < j; i++) {
if (this.items[i] > this.items[i + 1]) {
this.swap(i, i + 1);
}
}
}
}
2.选择排序
代码及详解:
图解:
//2.选择排序(时间复杂度O(n^2))
//在冒泡排序的基础上改进交换次数
ArrayList.prototype.selectionSort = function() {
//原理分析:重复比较选出最小的元素,将每次选出的最小元素交换至已排序数组的最后(与未排序数组的第一个元素交换),直至未排序元素个数等于1个
//第1次 i = 0,循环比较至i = length - 1,选出最小的值与i = 0 的元素交换
//第2次 i = 1,循环比较至i = length - 1,选出最小的值与i = 1 的元素交换
//第3次 i = 2,循环比较至i = length - 1,选出最小的值与i = 2 的元素交换
//第n次 i = n-1,循环比较至i = length - 1,选出最小的值与i = n 的元素交换
//最后一次 i = length - 2 与i = length - 1比较
for (var j = 0; j < this.items.length - 1; j++) {
var min = j;
for (var i = min + 1; i < this.items.length; i++) {
if (this.items[i] < this.items[min]) {
min = i;
}
}
this.swap(min, j);
}
}
3.插入排序
代码及详解:
图解:
//3.插入排序O(n^2)
ArrayList.prototype.insertSort = function() {
//原理分析:将第一个元素看成是有序的部分,从第二个元素开始取出元素与有序部分的元素从后往前比较,将较大的元素往后移,直至找到相应位置
//第1次 i = 1,与有序部分(数组的第一个元素)比较,若较小,则将较大部分往后移,若较大则,直接插入末尾(不需要移动)
//第2次 i = 2,与有序部分(数组的第一、二个元素)比较,若较小,则将较大部分往后移
//第n次 i = n,与有序部分(数组的前n个元素)比较,若较小,则将较大部分往后移
for (var i = 1; i < this.items.length; i++) { //将第一个元素看成有序部分,从第二个元素开始对有序部分进行比较
var temp = this.items[i];
for (var j = i - 1; j >= 0; j--) { //从有序部分从后往前与插入元素进行比较
if (this.items[j] > temp) {
this.items[j + 1] = this.items[j];
} else {
break;
}
}
this.items[j + 1] = temp;
}
}
二、高级排序
1.希尔排序
个人建议:先深刻理解插入排序,再学希尔排序
代码及详解:
图解:
//4.希尔排序
ArrayList.prototype.shellSort = function() {
//原理分析:对原数组进行间隔不断缩小的分组插入排序(对插入排序的改进版)
//第1次:对数组进行间隔length/2的分组插入排序
//解释:将每隔length/2的所有数组元素看成一个数组进行插入排序
//注意:书写代码时应注意下标增量应该是length/2
//第2次:对数组进行间隔length/4的分组插入排序
//第2次:对数组进行间隔length/4的分组插入排序
//第n次:对数组进行间隔length/2^n的分组插入排序
//最后一次:对数组进行间隔1的分组排序
//获取数组长度
var length = this.items.length;
//设置初始间隔
var gap = Math.floor(length / 2);
while (gap >= 1) { //间隔大于1时不断进行分组插入排序
for (var i = gap; i < length; i++) { //第一个间隔的远古三为所有分组的第一个元素,默认为有序的部分
var temp = this.items[i];
for (var j = i - gap; j >= 0; j = j - gap) {
//循环对分为一组的元素进行类似插入排序的操作(判断前面的元素是否比后面的大,如果是,前面的元素往后移动,接着继续往前比较,直至大于前面的元素,插入该元素的后面)
if (this.items[j] > temp) {
this.items[j + gap] = this.items[j];
} else {
break;
}
}
this.items[j + gap] = temp;
}
gap = Math.floor(gap / 2);
}
}
2.快速排序
代码及详解:
图解:
//5.快速排序
// 原理:
//1.先从数列中取出一个数作为基准数。
//2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
//3.再对左右区间重复第二步,直到各区间只有一个数。
/*取第一个作为参考值,从(end)后找小于参考值的数,
填在参考值的坑(填坑后原来的值的位置相当于一个坑),再从(start)头开始找大于参考值的数,
填上一个坑,重复填坑,直至start=end时,此时坑的位置就是参考值的位置,参考值左边是小于参考值的数,右边是大于参考值的数
再递归对两边的数组也进行同样的操作,直至两边的数组只有一个元素*/
ArrayList.prototype.fastSort = function(start, end) {
if (start < end) {
//如果start不小于end则递归结束
var i = start;
var j = end;
var temp = this.items[start];
while (i < j) {
while (i < j && this.items[j] >= temp) {
//从后找出小于参考值的数
j--;
}
if (i < j) {
//若找到,则填坑
this.items[i++] = this.items[j];
}
while (i < j && this.items[i] < temp) {
i++;
}
if (i < j) {
this.items[j--] = this.items[i];
}
}
this.items[i] = temp;
this.fastSort(start, i - 1);
this.fastSort(i + 1, end);
}
}
总结
此文章皆是本人理解手打的代码,希望能帮到需要的人,需要改进的地方欢迎各位大佬点评