数组排序
- 排序,就是把一个乱序的数组,通过我们的处理,让他变成一个有序的数组
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. 冒泡排序
- 先遍历数组,让挨着的两个进行比较,如果前一个比后一个大,那么就把两个换个位置
- 数组遍历一遍以后,那么最后一个数字就是最大的那个了
- 然后进行第二遍的遍历,还是按照之前的规则,第二大的数字就会跑到倒数第二的位置
- 依次类推,最后就会按照顺序把数组排好了
- 进行排序:
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
- 优化代码:
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 个是最小的数字的索引
- 在遍历一次数组,找到比我小的那个数字索引
- 遍历结束后换个位置
- 以此类推,就能把数组排序好了
- 进行排序
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
- 优化代码
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