排序算法如下----冒泡排序、快速排序、选择排序、插入排序、希尔排序

  • 插入排序
  • 二分插入排序
  • 希尔排序
  • 冒泡排序
  • 快速排序
  • 选择排序

1、插入排序

最普通的排序算法, 从数组下标1开始每增1项排序一次,越往后遍历次数越多
在这里插入图片描述

//插入排序
function sort(arr){
	var copyArr = [...arr]     // 复制一个复本出来
	for(let i=1;i<copyArr.length;i++){
		var prev = i - 1,temp = copyArr[i];
		while(prev>=0 && temp<copyArr[prev]){
			// 后  > 前,互换位置
		    [copyArr[prev+1],copyArr[prev] ] = [copyArr[prev],copyArr[prev+1]];
			prev-- ;
		}
	}
	return copyArr;
}
var list = [100,-5,10,0,0,-3,22,405,1,-3,96]
console.log(sort(list));

2、二分插入排序

插入排序的一种优化实现, 通过二分法减少遍历时间。

先在有序区通过二分查找的方法找到移动元素的起始位置,
然后通过这个起始位置将后面所有的元素后移
在这里插入图片描述

// 先在有序区通过二分查找的方法找到移动元素的起始位置,
// 然后通过这个起始位置将后面所有的元素后移
function sort(arr){
	var result = [...arr],temp,low,high,mid;
	for(let i=1;i<result.length;i++){
		temp = result[i];
		low = 0;
		high = i - 1;
		while(low<=high){
			mid = Math.ceil((low+high)/2)
			if(result[mid]>temp) high = mid - 1;
			else low = mid + 1;
		}
		//比当前temp大的值,全部向后移动一下
		//注意这里是倒序,把第一项向后移动一位
        for(let j = i - 1; j >= high+1; j--){
	      result[j+1] = result[j];            
	    }
	    result[high+1] = temp;
           
	}
	return result;
}

3、希尔排序

算法描述

先将整个待排序记录序列分割成若干个子序列,在序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
在这里插入图片描述

编码
// 希尔排序:先将整个待排序记录序列分割成若干个子序列
// 在序列内分别进行直接插入排序,待整个序列基本有序时,
// 再对全体记录进行一次直接插入排序
function shellSort(arr){
	var len = arr.length,
		temp,
		gap = 1;
	while(gap < len / 3){ //动态定义间隔序列
		gap = gap * 3 + 1;
	}
	for(gap; gap > 0; gap = Math.floor(gap / 3)){
		for(var i = gap; i < len; i++){     // 4--7
			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;
}

var test = [1,10,-3,100,5,67,34];
var sortTest = shellSort(test);
console.log(sortTest);

4、冒泡排序(每次遍历相邻互换

算法描述

(1)比较相邻的元素。如果第一个比第二个大,就交换它们两个;
(2)第一层for循环的第一次遍历完,数组最后的元素应该会是最大的数;,
第一层for循环的第二次遍历完,数组倒数第二的元素应该会是第二大的数;

(3)直到第一层for循环彻底完成,则数组就将会是从小到大排列;
在这里插入图片描述

编码
function sort(arr){
    for (var i = 1; i <arr.length; i++) {     //
        for (var j = 0; j <arr.length-i; j++) {     // 注意这里在,最后i项已经是最大的,不需要再遍历                     
           if(arr[j]>arr[j+1]){    //需要交换位置
               // var temp=arr[j];
              //  arr[j]=arr[j+1];
              //  arr[j+1]=temp;
              [arr[j+1], arr[j]] = [arr[j], arr[j+1]]
            }
        };
    };
    return arr.toString();
}
console.log(sort([23,45,18,37,92,13,24]));

5、快速排序(分区比较,直到每个区就一个)

算法描述

(1)先从数列中取出一个数作为“基准”
(2)分区过程:将比这个“基准”大的数全放到“基准”的右边,小于或等于“基准”的数全放到“基准”的左边。
(3)再对左右区间重复第二步,直到各区间只有一个数。
在这里插入图片描述

编码
function quickSort(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 quickSort(left).concat([pivot], quickSort(right)); //链接左数组、基准数构成的数组、右数组
};

var test = [1,10,-3,100,5,67,34];
var sortTest = quickSort(test);
console.log(sortTest);

6、选择排序 (每次遍历选最值)

算法描述

(1)遍历未排序的区域,将最小值的下标暂定为当前遍历的下标i;
(2)拿当前元素之后的元素与当前遍历的元素比较,若比其小,则修改最小下标。最终确定最小值所在的下标。
(3) 如果当前遍历的元素的下标与最小值的下标不一致,则互换位置
(4)重复第二步、第三步,直到所有元素均排序完毕。

编码
function selectSort(arr) {
  const len = arr.length
  for (let i = 0; i < len - 1; i++) { // 遍历未排序的区域
    // 将最小值的下标暂定为i
    let minIndex = i
    // 依次与它右侧元素比较
    for (let j = i+1; j < len; j++) {
      if (arr[minIndex] > arr[j]) {
        // 找到一个更小的值, 更新一下最小值的下标
        minIndex = j
      }
    }
    // 一旦minIndex有变化(发现最小值的下标不是i)
    if (minIndex!==i) {
      [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]
    }
  }

  return arr
}

var test = [1,10,-3,100,5,67,34];
var sortTest = selectSort(test);
console.log(sortTest);

参考链接
快速排序:https://segmentfault.com/a/1190000009426421
选择排序:https://segmentfault.com/a/1190000009366805
希尔排序:https://segmentfault.com/a/1190000009461832
常见排序:https://www.cnblogs.com/wteam-xq/p/4752610.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值