几种基本的排序算法总结

准备函数

	var arr = []
	function swap(arr, a, b) {  //交换函数
		var temp = arr[a]
		arr[a] = arr[b]
		arr[b] = temp
	}
	function random_arr (){  //生成随机数组的函数
		let long = Math.floor(Math.random()*100+1)
		for(var x = 0; x < long; x++) {
			arr.push(Math.floor(Math.random()*100))
		}
		console.log(arr)
	}
	random_arr()

冒泡排序

算法思路:

遍历数组, 将相邻两个数之间两辆比较, 如果前面的数比后面的数大, 就交换位置, 然后继续将这个数跟后面相邻的数比较如果前面的数比后面的数小, 就用下一个数跟后面相邻的数继续比较

function bubble(arr) {
		for(var i = arr.length-1; i >= 0; i--) {
			for(var j = 0; j <= i; j++) {
				if(arr[j] > arr[j+1]) {
					swap(arr, j, j+1)
				}
			}
		}
		console.log(arr)
	}
bubble(arr)

选择排序

算法思路:

将第一个数与后面的没一个数进行比较, 如果有存在比第一个数小的数, 则交换位置, 然后用这个较小数继续之前的位置向后比较, 经过一圈遍历后, 数组第一位的数就是跟个数组的最小值, 然后在用第二个数跟后面的所有数一次比较进行上述操作

	function chose(arr) {
		for(var i = 0; i<arr.length; i++) {
			for(var j = i+1; j<arr.length; j++) {
				if(arr[i] > arr[j]) {
					swap(arr, i, j)
				}
			}
		}
		console.log(arr)
	}
	chose(arr)

插入排序

算法思路:

遍历整个数组, 将遍历项与其之前的项从后往前做比较, 如果他前面的数大于遍历项, 则交换位置, 直到他前面的数小于遍历项为止

	function fuck_sort(arr) {
		for(var i = 1; i < arr.length; i++) {
			for (var j = i; j > 0; j--) {
				if(arr[j]<arr[j-1]) {
					swap(arr, j, j-1)
				}
			}
		}
		console.log(arr)
	}
	fuck_sort(arr)

归并排序

算法思路:

将一个数组, 对半分割, 递归执行, 直到被分割后的数组只剩下一个数, 然后利用外排的方式将分割好的数组进行排序然后复写到原数组中
在这里插入图片描述

function guibing(arr,low,height) {
		var mid = low+Math.floor((height-low)/2)
		if(low === height) {
			return
		}
		guibing(arr, low, mid)
		guibing(arr, mid+1, height)
		sort(arr, low, height, mid)
	}
	function sort(arr, low, height, mid) {
		var temp = []
		var p1 = low
		var p2 = mid+1
		while (true){
			if (arr[p1] >= arr[p2]) {
				temp.push(arr[p2++])
			}else {
				temp.push(arr[p1++])
			}
			if(p1 > mid) {
				for(var j = p2; j <= height; j++) {
					temp.push(arr[j])
				}
				break
			}
			if(p2 > height) {
				for(var j = p1; j < mid+1; j++) {
					temp.push(arr[j])
				}
				break
			}
		}

		for(var i = 0; i <= temp.length-1; i++) {
			arr[i+low] = temp[i]
		}
	}
	guibing(arr, 0, arr.length-1)
	console.log(arr)

或者

function guibing2(arr) {
		if(arr.length === 1) {
			return arr
		}
		var mid = Math.floor(arr.length/2)
		var left = arr.slice(0,mid)  //slice()是数组截取方法
		var right = arr.slice(mid, arr.length)     
		return sort2(guibing2(left), guibing2(right))
	}
	function sort2(left, right) {
		var temp = []
		while(left.length > 0 && right.length > 0) {
			if(left[0] <= right[0]) {
				temp.push(left.shift())
			}else {
				temp.push(right.shift())
			}
		}
		return temp.concat(left).concat(right)   //concat()是数组拼接方法
	}
	console.log(guibing2(arr))

快速排序

算法思路:

在数组中随便找一个数做基准数, 将比这个基准数大的数放到这个数的右侧, 将比这个基准数小的数, 放到这个数的左侧, 然后在基准数的小于区和大于区继续递归执行上述操作

function range(arr, l, r) {
		var less = l - 1
		var more = r
		while( l < more ) {
			if(arr[l] > arr[r]) {
				swap(arr, l, --more)
			}else if(arr[l] < arr[r]) {
				swap(arr, l++, ++less)
			}else {
				l++
			}
		}
		swap(arr, r, more)
		return [less+1,more]
	}
	function quick(arr, l, r) {
		if(l < r) {
			var scale = range(arr, l, r)
			quick(arr, l, scale[0]-1)
			quick(arr, scale[1]+1, r)
		}
	}
	quick(arr, 0, arr.length-1)
	console.log(arr)

或者

function quick2(arr) {
		if(arr.length === 0 ) {
			return []
		}
		var left = []
		var right = []
		var middle = []
		var index =Math.round(Math.random()*(arr.length-1))
		for(var i = 0; i<arr.length; i++) {
			if(arr[i] < arr[index]) {
				left.push(arr[i])
			}else if(arr[i] > arr[index]) {
				right.push(arr[i])
			}else {
				middle.push(arr[i])
			}
		}
		return quick2(left).concat(middle).concat(quick2(right))
	}
	console.log(quick2(arr))

堆排序

算法思路:

因为堆的结构就是一个完全二叉树, 所以我们可以把数组的结构也想象成一个完全二叉树, 首先将数组变成一个大根堆, 然后将数组的第一位与数组的最后一位进行交换, 将数组的遍历范围减少一位, 此时数组的最后一位就是最大值了, 然后再将二叉树的头节点, 跟其左右两孩子最大的那个作比较, 如果孩子节点大于父节点, 就交换位置, 然后利用原来的那个父节点继续跟左右孩子作比较,比较结束后, 又形成了一个大根堆, 继续将二叉树的头结点跟二叉树的倒数第二位作交换, 将数组的遍历范围再减少一位, 重复执行上述操作.
在这里插入图片描述

function dui_sort(arr) {
		dui(arr)
		var long = arr.length
		swap(arr, 0, --long)
		while(long > 0) {
			var j = 0
			var left = j*2+1
			while(left<long) {
				largest = left+1<long && arr[left+1] >arr[left] ? left+1 : left
				largest = arr[largest] > arr[j] ? largest : j
				if(largest === j) {
					break
				}
				swap(arr, largest, j)
				j = largest
				left = j*2+1
			}
			swap(arr, 0, --long)
		}
	}


	function dui(arr) {
		for(var i = 0; i < arr.length; i++) {
			var j = i
			while (arr[j] > arr[Math.floor((j-1)/2)]) {
				swap(arr, j, Math.floor((j-1)/2))
				j = Math.floor((j-1)/2)
			}
		}
	}
	dui_sort(arr)
	console.log(arr)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IsQtion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值