第七章 数组(下)

148 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

前言

数组算法总结啦!!! 来啦!!!来啦!!!

快速排序

通过递归将数据分解成一个个的小模块,调用中间值之后,进行比对,分解成两个模块,在理由两个模块重新进行比对

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; 
}