JS实现常见的六大排序

1 冒泡排序

思想:让相邻的两个数一直作比较,直到完成排序。
时间复杂度:O( n² )
稳定度:稳定
代码实现:
	var arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
	for(var i =0 ; i < arr.length ; i++ ){ // i用来判断当前冒泡排序从位置几开始的
		for(var j = 0 ; j < arr.length ; j++){ // j用来判断相邻两个数位置是否交换
			if(arr[j] > arr[j+1]){
				var temp = arr[j]
				arr[j] = arr[j+1]
				arr[j+1] = temp
			}
		}
	} 

冒泡排序

2 选择排序

思想:
  • 假设第一个数为minNum,其下标为minIndex
  • 用这个minNum和剩余的所有数比较,找出比第一个数还小的minNum,记录其minIndex;
  • 然后将其找出的minNum的minIndex与第一个默认的minNum的minIndex做交换;
  • 循环每个位置,直到完成排序
时间复杂度:O( n² )
稳定度:稳定
代码实现:
	var brr= [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
	var minIndex, temp
	function selectionSort (arr) {
		for(var i = 0 ; i < arr.length - 1 ; i++){
			minIndex = i // 默认第一个数为minNum,并记录它的minIndex
			for(var j = i + 1 ; j < arr.length ; j++){
				if(arr[j] < arr[minIndex]){ // 如果arr[j] < 默认的minNum
					minIndex = j // 记录这个新的minNum的minIndex
				}
			}
			// 找到一趟下来的最小minNum及其minIndex,并交换位置
			temp = arr[i]
			arr[i] = arr[minIndex]
			arr[minIndex] = temp
		}
		return arr
	} 
	selectionSort(brr)

选择排序

3 插入排序

思想:
  • 从第二数开始,和前面已排好的序作比较,是否插入(>前 , <后)
时间复杂度:O( n² )
稳定性:稳定
    // 直接比较前后的两个值
	var brr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
	var temp
	function insertSort (arr) {
	 for(var i = 1 ; i < arr.length ; i++){ // i用来判断当前循环做插入的是哪一个值的下标
	  for(j = i ; j - 1 >= 0 ; j--){// j用来判断当前当前的值和前一个值,是否做交换
	    if(arr[j] < arr[j-1]){ // 如果当前值小于前一个值,则进行交换
	     temp = arr[j]
	     arr[j] = arr[j-1]
	     arr[j-1] = temp
	    }
	  }
	 }
	 return arr
	}
	insertSort(brr)
	
或者:
    // 利用下标比较值
	var brr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
	var temp,curIndex
	function insertSort (arr) {
		for(var i = 1 ; i < arr.length ; i++){
			curIndex = i // 当前插入的值下标为i
			for(j = i - 1 ; j >= 0 ; j--){
				if(arr[curIndex] < arr[j]){ // 如果当前值小于它前面的值,则需要做交换
					temp = arr[j]
					arr[j] = arr[curIndex]
					arr[curIndex] = temp
					curIndex = j // 当两个值交换之后,当前做插入的这个值下标也随之改变成前一个
				}
			}
		}
		return arr
	}
	console.log(insertSort(brr)) 

在这里插入图片描述

4 快速排序

思想:
  1. 取到mid = arr.length / 2的中间值
  2. 将数组分为左右两个数组,以及取出来的中间值mid(splice方法)
  3. 分别对左右数组进行递归排序
  4. 将左右数组的递归跟中间值用concat函数返回
时间复杂度:O( nlogn )
稳定性:不稳定
var brr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
function quickSort (arr) {
	if(arr.length < 1){
		return arr
	}
	var left = []
	var right = []
	var index = Math.floor(arr.length / 2)
	var midNum = arr.splice(index, 1)[0]
	for(var i = 0 ; i < arr.length ; i++){
		if (arr[i] < midNum) {
			left.push(arr[i])
		} else{
			right.push(arr[i])
		}
	}
	return quickSort(left).concat(midNum, quickSort(right))
}
console.log(quickSort(brr))

快速排序

5 归并排序(二叉树排序)

思想:分治法。
  1. mid=arr.lengt/2,得到数组分割的中间值
  2. 将给定的数组从mid分为左右两个数组,只有在分之后数组的length<2时,才停止分配。
  3. 对分配的<2的数组进行merge(),最后会得到左右两个有序的数组。
  4. 在对左右两个有序的数组进行merge(),取地址为0的数进行比较,最终返回排序。
时间复杂度:O( nlogn )
稳定性:不稳定
var brr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
function mergeSort(arr) {
	var len = arr.length
	if (len < 2) {
		return arr // 分为1
	}
	// 取出mid, (0,mid)的数组left, (mid,end)的数组right
	var mid = Math.floor(len / 2),
	    left = arr.slice(0, mid),
		right = arr.slice(mid)
	
	// 和,将左右分割为1的数据进行合并
	return merge(mergeSort(left), mergeSort(right))
}
function merge(left, right) {
	// 定义一个返回的数组,初始为[]
	var result = []
	// 如果左右都存在
	while (left.lenght && right.length){
		// 取出[0]位置的左右数组的值进行比较
		if(left[0] <= right[0]){
			// 移除left[0],并push到result中
			result.push(left.shift())
		} else {
			// 移除right[0],并push到result中
			result.push(right.shift())
		}
	}
	// 由于上面的while执行的时候,只执行了if的一个条件,另外一个数组则没有push到result中
	while(left.length) {
		result.push(left.shift())
	}
	while(right.length) {
		result.push(right.shift())
	}
	return result
}
console.log(mergeSort(brr))

归并

归并排序图解

在这里插入图片描述

6 堆排序

思想:
  1. 构建大顶堆。
  2. 将堆的最后一个元素与堆顶做交换。
时间复杂度:O( nlogn )
稳定性:不稳定
function heapSort (arr) {
	for (var i = arr.length - 1 ; i > 0; i--) {
	// 1.建立大顶堆
	heapify(arr, i)
	// 2. 最后一个子节点跟第一元素交换
	swap(arr, 0, i)
	}
	return arr
}
function swap (arr, n, m) {
	var temp = arr[n]
	arr[n] = arr[m]
	arr[m] = temp
}
function heapify(arr, n) {
	// 先找出最后一个父节点
	for (let i = Math.floor((n-1) / 2); i >= 0; i--) {
		// 然后找出这个父节点的左孩子child
		var child = 2 * i + 1
		// 判断这个父节点是否存在右孩子,若右孩子存在,且 右孩子的值 > 左孩子的值 ,则child++
		if (child != n && arr[child] < arr[child+1]) {
			child++
		}
		// 最后,判断这个arr[child]和父节点的值,是否做交换,执行swap函数
		if (arr[child] > arr[i]) {
			swap(arr, child, i)
		}
	}
}
var brr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
console.log(heapSort(brr))

堆

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值