小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
前言
数组算法总结啦!!! 来啦!!!来啦!!!
快速排序
通过递归将数据分解成一个个的小模块,调用中间值之后,进行比对,分解成两个模块,在理由两个模块重新进行比对
function qSort(myArr) {
//递归停止的条件
if(myArr.length===0){
return[]
}
//设置小于中间值的数组
let smallArr=[]
//设置大于中间值的数组
let bigArr = []
//设置中间值
let pivot = myArr[0]
for(let i =1;i<myArr.length;i++){
//进行比对 如果该项大于中间值,就放入大于数组中,如果小于
//放入小于的数组中
//这样比对后 无论怎么样 大于的数组中的任意数都大于中间值
//小于的数组中任意数都小于中间值
if(myArr[i]<pivot){
smallArr.push(myArr[i])
}else{
bigArr.push(myArr[i])
}
return [...qSort(smallArr),pivot,...pivot(bigArr)]
}
插入排序
从数组第2个元素开始抽取元素。
把它与左边第一个元素比较,如果左边第一个元素比它大,则继续与左边第二个元素比较下去,直到遇到不比它大的元素,然后插到这个元素的右边。
继续选取第3,4,….n个元素,重复步骤 2 ,选择适当的位置插入。
冒泡、选择都是把未排序的和未排序的进行比较换位 而插入排序的思想是把未排序的和已经排好序的进行比较换位
function insertSort(myArr) {
let temp, j;
for (let i = 1; i < myArr.length; i++) {
temp = myArr[i]; j = i;
// 这里是和 左侧进行比较,如果小于前面就进行换位
while (j > 0 && myArr[j - 1] > temp) {
myArr[j] = myArr[j - 1]; j--;
}
myArr[j] = temp;
}
归并排序
归并排序的思想是,拆,拆成足够小的模块后,知道每个模块就剩下一个元素后,在进行合并,从最小的数组开始,两两合并,这样可以保证每次都只需遍历一次数据,直到合并到原数据的大小为止
辅助函数
// 融合两个有序数组,这里实际上是将数组 arr 分为两个数组
function mergeArray(arr, first, mid, last, temp) {
let i = first;
let m = mid;
let j = mid+1;
let n = last;
let k = 0;
while(i<=m && j<=n) {
if(arr[i] < arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++]; }
}
while(i<=m) {
temp[k++] = arr[i++];
}
while(j<=n) {
temp[k++] = arr[j++];
}
for(let l=0; l<k;l++) {
arr[first+l] = trmp[l]
}
return arr;
}
合并函数
// 递归实现归并排序
// 这里需要调用
function mergeSort(arr, first, last, temp) {
if(first<last){
let mid = Math.floor((first+last)/2);
mergeSort(arr, first, mid, temp); // 左子数组有序
mergeSort(arr, mid+1, last, temp); // 右子数组有序
arr = mergeArray(arr, first, mid, last, temp);
}
return arr;
}
调用函数
function use(){
var arr = [10, 3, 1, 5, 11, 2, 0, 6, 3,3,4,5,6,6,7,8,9,1,2,3,4];
var temp = new Array();
var arr1 = mergeSort(arr, 0 ,arr.length-1, temp);
}
冒泡排序
比较两个相邻的元素,如果后一个比前一个大,则交换位置
第一轮的时候最后一个元素应该是最大的一个
按照第一步的方法进行两个相邻的元素的比较,由于最后一个元素已经是最大的了,所以最后一个元素不用比较
function jssort(myArr) {
for (let i = 0; i < myArr.length - 1; i++) {
//要循环多少次 //开闭原则。(写在第一个for循环里,是为了,
//每轮比较初始化bool变量变为true。)
var bool=true;
//乍一看好像我们什么也没有做
//仔细看 我们在 myArr.length - 1 -i 这里加了 -i的改动
//为什么要真这样呢? //每轮比较少比较一次。(每一轮都会比较出一个最大值,
//然后后一轮没有必要再比较了,
//所以每比较一轮,就少比较一次。。。)
for (let j = 0; j < myArr.length - 1 -i; j++) {
//要移动几次
if (myArr[j] > myArr[j + 1]) {
[myArr[j], myArr[j + 1]] = [myArr[j + 1], myArr[j]] bool=false;
}
}
//bool这个变量默认值为true;如果本轮比较有一对元素相互交换位置,
//那么也不能跳出循环。
//但是,如果本轮比较没有任何元素相互交换位置,那么说明已经比较完成,
//可以跳出循环。
if(bool){
break;
}
}
return myArr;
}
希尔排序
希尔排序的话 就是在递归的同时 把数据拆分成多个数据模块
function shellSort(arr) {
// 首先确定号数组的长度
var len = arr.length;
// 对数组进行第一次拆分
//这里复习一下for循环
// for循环 定义 条件 执行三个方法
// 在我们初始化判断完毕会分为两个小组 小组1和小组2
for(var gap = Math.floor(len / 2); gap > 0; gap = Math.floor(gap / 2)) {
// 注意:这里是多个分组交替执行
// 当数组长度为10时
//第一次数组分成了5组
//那就是 0-5,1-6以此类推进行对比
//第二次后分成了2组
//那就是 0-2,1-3 以此类推
for(var i = gap; i < len; i++) {
var j = i;
var current = arr[i];
// 这里是插入算法,和左边的进行比较,如果小于左边的就和他进行交换
while(j - gap >= 0 && current < arr[j - gap]) {
console.log(j - gap)
arr[j] = arr[j - gap];
j = j - gap;
}
arr[j] = current;
}
}
return arr;
}
选择排序
选择排序算法:先并不急于调换位置,先从A[1]开始逐个检查,看哪个数最小就记下该数所在的位置P,等一躺扫描完毕,再把A[P]和A[1]对调,这时A[1]到A[10]中最小的数据就换到了最前面的位置。
总结
function selectSort(myArr) {
let minIndex, temp;
for (let i = 0; i < myArr.length - 1; i++) {
minIndex = i;
for (let j = i + 1; j < myArr.length; j++) {
if (myArr[j] < myArr[minIndex]) {
minIndex = j;
}
}
//解构赋值
[myArr[i], myArr[minIndex]] = [myArr[minIndex], myArr[i]]
}
return myArr;
}