一、冒泡排序
算法描述:
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成。
时间复杂度:n * n
实例代码为:
function sort(arr) {
var len = arr.length - 1;
for(var i = len; i > 0; i--) {
for(var j = 0 ; j < i; j++) {
if (arr[j] > arr[j+1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp
}
}
}
return arr
}
console.log(sort([3,7,8,4,5,7,6,1,2]))
// (9) [1, 2, 3, 4, 5, 6, 7, 7, 8]
二、选择排序
算法描述:
n个元素的直接选择排序可经过n-1趟直接选择排序得到有序结果
- 每一趟在n个元素中选择最小的一个,将其放置在n个元素的一端
- 重复步骤一n次
时间复杂度:n * n
实例代码为:
function sort(arr) {
var len = arr.length
for(var i = 0; i < len; i++) {
for(var j = 0 ; j < len; j++) {
if (arr[i] < arr[j]) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr
}
console.log(sort([3,7,8,4,5,7,6,1,2]))
// (9) [1, 2, 3, 4, 5, 6, 7, 7, 8]
三、插入排序
算法描述:
通过构建有序序列,对于未排序的数据,在已排序序列中从后向前扫描,直到找到符合条件的位置,插入数据.
- 从第一个数据开始,默认它是在已排序的序列里面的
- 取下一个元素a,在已经排序的元素中从后向前扫描
- 若a小于已排序的序列中的元素b,则b的位置被a替换
- 将元素a重复上一步,直到在已排序的序列中找到一个元素小于或者等于a,即将a插入到该元素后面
- 重复步骤2-4
时间复杂度:n * n
实例代码为:
function sort(arr) {
var len = arr.length;
var preIndex, currentItem;
for(var i = 1; i < len; i++) {
preIndex = i - 1;
currentItem = arr[i];
while(preIndex >= 0 && arr[preIndex] >= currentItem) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = currentItem;
}
return arr
}
console.log(sort([3,2,8,4,5,7,6,1,7]))
// (9)Â [1, 2, 3, 4, 5, 6, 7, 7, 8]
四、归并排序
算法描述:
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
- 把长度为n的输入序列分成两个长度为n/2的子序列;
- 对这两个子序列分别采用归并排序;
- 将两个排序好的子序列合并成一个最终的排序序列。
时间复杂度:nlogn
实例代码为:
function merge(left, right) {
var resultArr = [];
while (left.length && right.length) {
resultArr.push(left[0] <= right[0] ? left.shift() : right.shift());
}
return resultArr.concat(left).concat(right);
}
function sortArr(arr) {
var len = arr.length;
if (len < 2) return arr;
var middle = len >> 1 // 取中位下标
return merge(sortArr(arr.slice(0, middle)), sortArr(arr.slice(middle)));
}
console.log(sortArr([3,7,8,4,5,7,6,1,2]))
// (9) [1, 2, 3, 4, 5, 6, 7, 7, 8]
归并排序是一种稳定的排序方法。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。代价是需要额外的内存空间
五、快速排序
利用分治策略来将一个序列分为两个子序列,
算法描述:
- 数组中挑出来第一个数据作为"基准"值
- 遍历数组,将数据与该基准值进行比较,比其小的放在左边,比其大的放在右边。在这个分区结束之后,该基准就处于数列的中间位置;
- 递归的把小于基准值的元素的子数列和大于基准值的子数列排序;
时间复杂度:nlogn
实例代码为:
function quickSort (arr) {
if (arr.length <= 1) return arr
var leftArr = [], rightArr = [];
for(var i = 1; i < arr.length; i++) {
arr[i] >= arr[0] ? rightArr.push(arr[i]) : leftArr.push(arr[i]);
}
return quickSort(leftArr).concat(arr[0]).concat(quickSort(rightArr))
}
console.log(quickSort([3,7,8,4,5,7,6,1,2]))
// (9) [1, 2, 3, 4, 5, 6, 7, 7, 8]