【JS】数组排序(六大方法)

文章目录

数组排序

  • 排序,就是把一个乱序的数组,通过我们的处理,让他变成一个有序的数组

1. sort()方法

  • sort() 数组对象排序 其原理是冒泡排序
  • reverse() 方法能够颠倒数组元素的排列顺序

例如:

var arr = [3,1,5,6,4,9,7,2,8];
var asc = arr.sort()
console.log(asc);	// 1,2,3,4,5,6,7,8,9
var desc = asc.reverse()
console.log(desc);	// 9,8,7,6,5,4,3,2,1

2. 冒泡排序

  • 先遍历数组,让挨着的两个进行比较,如果前一个比后一个大,那么就把两个换个位置
  • 数组遍历一遍以后,那么最后一个数字就是最大的那个了
  • 然后进行第二遍的遍历,还是按照之前的规则,第二大的数字就会跑到倒数第二的位置
  • 依次类推,最后就会按照顺序把数组排好了
  1. 进行排序:
var arr = [5,4,3,2,1];
console.log('初始数组:',arr);	// 	5,4,3,2,1
//一次次遍历,有多少个数就遍历多少次
for(var i = 0; i < arr.length; i++){
	//循环两两比较数组中的数字
	for(var j = 0; j < arr.length; j++){
		//if判断,如果数组中的当前一个比后一个大,那么两个交换一下位置
		if(arr[j] > arr[j + 1]){
			var tmp = arr[j];
			arr[j] = arr[j + 1];
			arr[j + 1] = tmp;
			console.log('i='+i,arr);
		}
	}
}
console.log('排序结束:',arr);	// 1,2,3,4,5

在这里插入图片描述

  1. 优化代码:
var arr = [5,4,3,2,1];
console.log('初始数组:',arr);	// 	5,4,3,2,1
/*数组长度为9,在第8次的时候,后面8个数字已经排序好
了,最小的数字已经交换到第1个数字位置,所以没必要再
一次从第1个开始进行两两交换比较了,即:arr.length-1*/
for (let i = 0; i < arr.length-1; i++){
	/*每次循环的时候都会把最后一个数字依次排在最后
	面,循环了几次,意味着后面已经排好了几个数,而
	那些已经排好的数也没必要再跟没排好的数进行比较
	即:数组长度length-已经循环的次数i*/
	for (let j = 0; j < arr.length - 1 - i; j++){
		if(arr[j] > arr[j + 1]){
			let tmp = arr[j];
			arr[j] = arr[j + 1];
			arr[j + 1] = tmp;
			console.log('i='+i,arr);
		}
	}
}
console.log('排序结束:',arr);	// 1,2,3,4,5

3. 选择排序

  • 先假定数组中的第 0 个就是最小的数字的索引
  • 然后遍历数组,只要有一个数字比我小,那么就替换之前记录的索引
  • 知道数组遍历结束后,就能找到最小的那个索引,然后让最小的索引换到第 0 个位置
  • 再来第二遍遍历,假定第 1 个是最小的数字的索引
  • 在遍历一次数组,找到比我小的那个数字索引
  • 遍历结束后换个位置
  • 以此类推,就能把数组排序好了
  1. 进行排序
var arr = [3,1,5,2,4];
console.log('初始数组:',arr);	// 	3,1,5,2,4
for(let i = 0; i< arr.length; i++){
	/*假定第 1 遍数组中的第 0 个是最小数字的索引
	第 2 遍的时候假定第 1 个,即假定第 i 个就行*/
	let minIndex = i;
	/*因为之前已经把最小的放在最前面了,后面的循环
	就不需要判断前面的了,直接从i+1开始*/
	for(let j = i+1; j < arr.length; j++){
		if(arr[j] < arr[minIndex]){
			minIndex = j;
		}
	}
	/*遍历结束后找到最小的索引
	第 1 趟的时候是和第 0 个交换,第 2 趟的时候和
	第 1 个交换,即直接和第 i 个交换就行
	*/
	let tmp = arr[minIndex];
	arr[minIndex] = arr[i];
	arr[i] = tmp;
	console.log('i='+i,arr);
}
console.log('排序结束:',arr);	// 1,2,3,4,5

在这里插入图片描述

  1. 优化代码
var arr = [3,1,5,2,4];
console.log('初始数组:',arr);	// 	3,1,5,2,4
/*和之前一样,倒数第二次排序完毕以后,就已经排好了,最后一次没有必要了*/
for(let i = 0; i< arr.length-1; i++){
	/*假定第 1 遍数组中的第 0 个是最小数字的索引
	第 2 遍的时候假定第 1 个,即假定第 i 个就行*/
	let minIndex = i;
	for(let j = i+1; j < arr.length; j++){
		if(arr[j] < arr[minIndex]){
			minIndex = j;
		}
	}
	/*遍历结束后找到最小的索引
	第 1 趟的时候是和第 0 个交换,第 2 趟的时候和
	第 1 个交换,即直接和第 i 个交换就行
	*/
	let tmp = arr[minIndex];
	arr[minIndex] = arr[i];
	arr[i] = tmp;
	console.log('i='+i,arr);
}
console.log(arr);	// 1,2,3,4,5

4. 插入排序

  • 假设前面 n-1 的元素已经排好序,将第n个元素插入到前面已经排好的序列中。
var arr = [5,4,3,2,1];
console.log('初始数组:',arr);	// 	5,4,3,2,1
for(var i = 0; i < arr.length; i++) {	
	for(var n = i; n >= 0; n--) {
		if(arr[n] > arr[n+1]){
			var temp = arr[n];
			arr[n] = arr[n+1];
			arr[n+1] = temp;
			console.log('i='+i,arr);		
		}	
 	}
}
console.log('排序结束:',arr);	// 1,2,3,4,5

在这里插入图片描述

5. 快速排序

  • 快速排序冒泡排序的改进算法。
  • 设定分界值,根据分界值将数组分为左右两部分。其中一部分的所有数据都比另外一部分的所有数据都比另一部分的所有数据小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
var arr = [3,1,5,2,4];
console.log('初始数组:',arr);	// 	3,1,5,2,4
var sum = 0;
function quickSort (arr) {
    if (arr.length <= 1) {
        return arr;
    }
    var medianIndex = Math.floor(arr.length / 2); // 找分界值索引
    var medianValue = arr.splice(medianIndex, 1); // 把分界值从原数组中取出并删除
    var left = []; 	// 比分界值小的,放左边
    var right = [];	// 比分界值大的,放右边
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] < medianValue) {
            left.push(arr[i])
        } else {
            right.push(arr[i])
        }
        sum++;
    }
    console.log(medianIndex, medianValue, left, right)
    return quickSort(left).concat(medianValue,quickSort(right));	// 最后进行拼接
};
console.log('排序结束:',quickSort(arr));	// 1,2,3,4,5

在这里插入图片描述

6. 希尔排序

  • 希尔排序插入排序的改进算法。
  • 把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个数据列恰好被分成一组,算法便终止。
var arr = [3,1,5,2,4];
console.log('初始数组:',arr);	// 	3,1,5,2,4
var sum = 0;
// var fraction = Math.floor(arr.length / 2) => 定义间隔区间
// fraction = Math.floor(fraction / 2) => 循环中不断切割区间
for (var fraction = Math.floor(arr.length / 2); fraction > 0; fraction = Math.floor(fraction / 2)) {
	// 以间隔值开始遍历
	for (var i = fraction; i < arr.length; i++) {
		// 如果前面一个大于后面一个
		for (var j = i - fraction; j >= 0 && arr[j] > arr[fraction + j]; j -= fraction) {
			var temp = arr[j];
			arr[j] = arr[fraction + j]; // 后移
			arr[fraction + j] = temp; // 填补
			console.log('i='+i,arr);	
			sum++;
		}
	}
}
console.log('排序结束:',arr);	// 1,2,3,4,5

在这里插入图片描述


http://www.niftyadmin.cn/n/509594.html

相关文章

javaScript 字符串压缩

字符串压缩。利用字符重复出现的次数&#xff0c;编写一种方法&#xff0c;实现基本的字符串压缩功能。比如&#xff0c;字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短&#xff0c;则返回原先的字符串。你可以假设字符串中只包含大小写英文字母&#xff08;a…

uniapp仿oppo官网

用的oppo的接口&#xff0c;写了一半&#xff0c;有的接口调不通就搁置了&#xff0c;有兴趣的可以看下 地址

【JS】for、for-in、for-of 循环的区别

文章目录1. for 循环2. for in 循环【ES5】3. for of 循环【ES6】1. for 循环 因为数组的索引就可以获取数组中的内容&#xff0c;数组的索引又是按照 0-n 顺序排列&#xff0c;我们就可以使用 for 循环来循环数组&#xff0c;因为 for 循环我们也可以设置成 0-n 顺序增加&…

javaScript 41. 缺失的第一个正数

给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,0] 输出&#xff1a;3 来源&#xff1a;力扣&#xff08;LeetCode&…

【ES6】...扩展运算符

文章目录扩展运算符一、在函数中使用1.1 传递实参1.2 接收形参1.3 new 表达式二、在数组中使用2.1 合并数组2.2 拷贝数组三、在对象中使用3.1 合并对象3.2 拷贝对象扩展运算符 ES6 里面号新添加了一个运算符...&#xff0c;叫做扩展运算符&#xff0c;又称&#xff08;Spread …

js 回溯全排列

给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 来源&#xff1a;力扣&#xff08;LeetCod…

【ES6】let 和 const 详解

文章目录一、let 和 const 共同点1. 不重复声明2. 无变量提升3. 作用域限制4. 暂时性死区二、let 和 const 不同点1. 声明时区别2. 赋值时区别一、let 和 const 共同点 我们以前都是使用var关键字来声明变量的在ES6的时候&#xff0c;多了两个关键字let和const&#xff0c;也是…

【ES6】解构赋值

文章目录一、解构赋值二、解构数组1. 变量赋值2. 交换变量3. 默认值4. 不完全解构5. 解构数组嵌套6. 与...运算符结合使用三、解构对象1. 获取成员2. 对象赋值3. 默认值4. 解构嵌套对象四、解构函数1. 函数的参数2. 函数返回值四、其他解构1. 字符串3. 其他数据类型一、解构赋值…