javascript LFU 算法 js的算法_Math

 

 

一、冒泡排序

原理:

  1、相邻元素两两比较,如果前一个比后一个大,则交换位置

  2、第一轮比较完毕,最后一个元素是最大的元素

  3、第二轮比较开始,此时最后一个元素是最大的,所以不参与比较

代码:

function bubble(arr = [3, 1, 7, 4, 8, 2, 6]){
            let len = arr.length

            for(let i = 0; i < len - 1; i++){

                for(let j = 0; j < len - 1 - i; j++){
                    if(arr[j] > arr[j + 1]){
                        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
                    }
                }
            }

            return arr
        }

 

二、选择排序

原理:

  1、首先在未排序序列中找到最小元素,存放到排序序列的起始位置

  2、第一轮比较完毕,第一个元素是最小的元素

  3、第二轮比较开始,此时第一个元素是最小的,所以不参与比较

代码:

function choose(arr = [5, 2, 7, 1, 4, 9, 6]) {
            let minIndex
            for (var i = 0; i < arr.length - 1; i++) {
                minIndex = i;
                for (var j = i + 1; j < arr.length; j++) {

                    if (arr[j] < arr[minIndex]) {
                        minIndex = j    // 将最小数的索引保存
                    }
                }
                [arr[minIndex], arr[i]] = [arr[i], arr[minIndex]]
            }

            return arr
        }

 

三、插入排序(玩扑克牌的算法)

原理:

  1、每次拿到一张牌,按大小顺序将其插入到合适的位置

代码:

function insert(arr = [2, 5, 3, 7, 1, 11, 4]){
            for(let i = 1; i < arr.length; i++){
                let temp = arr[i]
                let j = i
      arr[j] = arr[j - 1]
      j--
                arr[j] = temp
            }

            return arr
        }

 

四、希尔排序(缩小增量排序)

原理:

  1、将整个待排序记录序列分割为若干个子序列

  2、然后对每一个子序列进行直接插入排序

代码:

function shellSort(arr = [3, 5, 1, 8, 2, 6]) {
            let gap = Math.floor(arr.length / 2)

            while(1 <= gap){
                for(let i = gap; i < arr.length; i++){
                    let temp = arr[i]
                    let j = 0

                    for(j = i - gap; j >=0 && temp < arr[j]; j-=gap){
                        arr[j + gap] = arr[j]
                    }
                    arr[j + gap] = temp
                }

                gap = Math.floor(gap / 2)
            }

            return arr
        }

 

五、归并排序

原理:

  1、把长度为n的输入序列分成两个长度为n/2的子序列

  2、对这两个子序列分别采用归并排序

  3、将两个排序好的子序列合并成一个最终的排序序列

代码:

function mergeSort(arr = [3, 7, 4, 1, 6, 5]){
            let len = arr.length
            if(len <= 1){
                return arr
            }

            let 
                num = Math.floor(len / 2),
                left = mergeSort(arr.slice(0, num))
                right = mergeSort(arr.slice(num, len))

            return merge(left, right)

            function merge(left, right){
                let l = 0, r = 0, result = []
                while(l < left.length && r < right.length){
                    if(left[l] < right[r]){
                        result.push(left[l])
                        l++
                    }else{
                        result.push(right[r])
                        r++
                    }
                }
                result = result.concat(left.slice(l, left.length))
                result = result.concat(right.slice(r, right.length))

                return result
            }
        }

六、快速排序

原理: 

1、找基准(一般是以中间项为基准)

2、遍历数组,小于基准的放在左边,大于基准的放在右边

 

3、递归

代码:

function quickSort(arr = [3, 7, 20, 1, 10, 6, 15, 5, 12]) {
            if (arr.length <= 1) return arr

            const leftArr, rightArr = [],
                let current = null

            current = arr.splice(0, 1)

            for (let i = 0; i < arr.length; i++) {
                arr[i] < current ? leftArr.push(arr[i]) : rightArr.push(arr[i])
            }

            return quickSort(leftArr).concat(current, quickSort(rightArr))
  }

 

七、堆排序(完全二叉树)

原理:

  1、将无序序列构建成一个堆,一般升序采用大顶堆,降序采用小顶堆

  2、将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端

  3、重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

代码:

// 构造大顶堆
        function shiftDown(arr, i, arrLenth){
            let temp = arr[i]
            for(let j = 2 * i + 1; j < arrLenth; j = 2 * i + 1){
                temp = arr[i]
                if(j + 1 < arrLenth && arr[j] < arr[j + 1]){
                    j++ //到两个孩子中较大的一个,再与父节点比较
                }
                if(temp < arr[j]){
                    [arr[i], arr[j]] = [arr[j], arr[i]]
                    i = j
                }else{
                    break
                }
            }
        }
        // 堆排序
        function heapSort(arr = [4, 6, 8, 5, 9]){
            // 从第一个非页子节点开始
            for(let i = Math.floor(arr.length / 2 - 1); i >= 0; i--){
                shiftDown(arr, i, arr.length)
            }
            // 排序,每一次for循环找出一个当前最大值,数组长度减一
            for(let i = Math.floor(arr.length - 1); i > 0; i--){
                [arr[i], arr[0]] = [arr[0], arr[i]] //根节点与最后一个节点交换
                shiftDown(arr, 0, i)
            }

            return arr
        }

 

八、计数排序

原理:

  1、查找待排序数组中最大的元素

  2、统计每个值为i的元素的出现次数并累计

  3、反向填充目标数组,将每个元素i放在新数组的第C[i]项,每放一个元素,计数-1

代码:

function countSort(nums = [2, 3, 8, 7, 1, 2, 7, 3]) {
     let arr = [];
            let max = Math.max(...nums);
            let min = Math.min(...nums);
            // 装桶
            for (let i = 0, len = nums.length; i < len; i++) {
                let temp = nums[i];
                arr[temp] = arr[temp] + 1 || 1;
            }

            let index = 0;
            // 还原原数组
            for (let i = min; i <= max; i++) {
                while (arr[i] > 0) {
                    nums[index++] = i;
                    arr[i]--;
                }
            }

            return nums
        }

 

九、桶排序

原理:

  1、设置一个定量的数组当作空桶

  2、遍历输入数据,并且把数据一个一个放到对应的桶里去

  3、对每个不是空的桶进行排序

  4、从不是空的桶里把排好序的数据拼接起来。

代码:

function bucket_sort(A = [29, 25, 3, 49, 9, 37, 21, 43], k = 5, s = 10) { //A排序数组,k桶子数量,s桶子空间尺度
            const buckets = Array.from({ length: k }, () => []) //创建桶子
            //把元素放入对应桶子
            for (let i = 0; i < A.length; i++) {
                //计算需要放入桶子序号
                const idx = ~~(A[i] / s)
                buckets[idx].push(A[i])
            }

            //对每个桶子进行排序
            for (let i = 0; i < buckets.length; i++) {
                //此处选取插入排序, 空间消耗少,元素少常数时间消耗短
                insert(buckets[i])
            }
           
            //把每个桶子数据合并
            return [].concat(...buckets)
        }

十、基数排序

原理:

  1、确定数组中的最高位数

  2、按数组中每个元素的个位大小进行排序,接着是十位、百位...

  3、类似桶排序

代码:

function radixSort(arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48], maxDigit = 2) {
            let mod = 10, dev = 1, counter = []
            for(let i = 0; i < maxDigit; i++, dev *= 10, mod *= 10){
                for(let j = 0; j < arr.length; j++){
                    let bucket = parseInt((arr[j] % mod) / dev)
                    if(counter[bucket] == null){
                        counter[bucket] = []
                    }
                    counter[bucket].push(arr[j])
                }

                let pos = 0
                for(let j = 0; j < counter.length; j++){
                    let value = null
                    if(counter[j] != null){
                        while((value = counter[j].shift()) != null){
                            arr[pos++] = value
                        }
                    }
                }
            }

            return arr
        }