数据结构之排序算法--------JavaScript篇

排序算法

简单排序算法

冒泡排序

像可乐里面的气泡一样,每一个数都自行的向上比较,如果符合就停下,不符合就继续冒泡

对未排序的元素从头到尾依次与相邻元素比较,如果不符合条件则调换位置,符合则进行下一个元素比较

在这里插入图片描述
时间复杂度 n 2 n^2 n2空间复杂度 1 1 1

稳定

 function bubbleSort (arr) {
     for(let i = 0;i<arr.length;i++) {
       for(let j = 0;j<arr.length;j++) {
           if(arr[j-1] > arr[j]) {
               let curren = arr[j-1]
               arr[j-1] = arr[j]
               arr[j] = curren 
           } else {
   
           }
       }
   }
 }

效率:10万数组

在这里插入图片描述

选择排序

每次循环找到最小(大)值,放到最前面的位置,依次类推

对于冒泡排序比较,减少交换次数,每次找到最值,避免多余的交换次数

在这里插入图片描述

时间复杂度 n 2 n^2 n2,空间复杂度 1 1 1,不稳定

function selectSort(arr) {
    let len = arr.length
    for(let i = 0; i< len; i++) {
        let curren = i
        for(let j = 0; j< len; j++ ) {
            if(arr[j] < arr[i]) {
                curren = j
            }
        }
        if(curren!= i) {
            let item = arr[i]
            arr[i] = arr[curren]
            arr[curren] = item
        }
            
    }
   	return arr
}

效率测试:10万数组

在这里插入图片描述

插入排序

简单排序中效率最高

从头到尾开始遍历,每一个元素都需要与左边的所有元素注意比较,如果符合条件就插入,不符合继续向前遍历

在这里插入图片描述

时间复杂度 n 2 n^2 n2,空间复杂度 1 1 1稳定

function insetSort(arr) {
       let index = 0
    for(var i = 1; i < arr.length; i++) {
     	index = i-1
        let curren = arr[index + 1]
        while(index >= 0&& arr[index] > curren ) {
            // 每次判断左边所有元素是否符合条件,不符合就调换位置
            arr[index +1] = arr[index]
            index--
        }
        arr[index + 1] = curren
    }
    return arr
}

效率测试:10万数组

在这里插入图片描述

高级排序

希尔排序

插入排序高配版,只不过插入排序是对整个数组直接排序,而希尔是通过间隔而不是相邻元素插入排序

在这里插入图片描述

时间复杂度 n 1.25 n^{1.25} n1.25,空间复杂度 1 1 1,不稳定

选择适合的增量:

  1. HIBBARD增量:奇数增量
  2. sedgewick增量: 9 4 i − 9 ∗ 2 i + 1 或 者 4 i − 3 2 i + 1 94^i -9*2^i +1或者4^i-32^i +1 94i92i+14i32i+1
function shellSort(arr) {
    let gap = Math.floor(arr.length /2)
    let temp ;
    while(gap >= 1) {
        // 这里对每一个分组进行插入排序
        for(var i = gap;i<arr.length;i++) {
			let j = i
       		temp = arr[i]
            while(arr[j - gap] > temp && j > gap -1) {
                arr[j] = arr[j-gap]
                j -= gap
            }
        }
        arr[j] = temp
        gap = Math.floor(gap/2)
    }
  
}

效率测试:100万的长度数组

在这里插入图片描述

快速排序

冒泡的高配版

选择一个标记,将所有大于这个标记放在左边.所有大于这个标记放在右边

在这里插入图片描述

时间复杂度 n l g n nlgn nlgn,空间复杂度 n l g n nlgn nlgn,不稳定

function quickSort(arr){
    if(arr.length <=1) return arr
    let right =[]
    let left = []
    let point = arr.shift()
    for(var i = 0; i < arr.length;i++) {
        if(arr[i] > point ) {
            right.push(arr[i])
        } else {
            left.push(arr[i])
        }
    }

    return quickSort(left).concat([point],quickSort(right))
}


效率测试:1千万的长度

在这里插入图片描述

堆排序

选择排序的高配版

将数据分成一个无序的二叉树,从底层开始搜索,将最大的移动的父节点,重复知道到根节点获取到最大值,然后调换位置,将根节点换到最后子节点,并且去除连接,重复上述过程

在这里插入图片描述

时间复杂度 n l o g 2 n nlog_2n nlog2n

空间复杂度 1 1 1
不稳定

var len = 0
function heapSort(arr) {
    // 建立大顶堆
    len = arr.length    
    for(var i = Math.floor(len/2);i>=0;i--)// 排序
    {
        heapFy(arr,i)
    }
    for(var i = arr.length-1; i > 0; i--) {
        let temp = arr[0]
        arr[0] = arr[i]
        arr[i] = temp
        len--
        // 调换之后,0对应的位置是比较小的,所有需要从0位置开始判断
        heapFy(arr, 0)
    }
    return arr
}
function heapFy(arr, i) {
    // 二叉树的对应的位置index
    var left = 2 * i + 1
    var right = 2 * i + 2 
    var largest = i
    // 跳过最下层的节点
    if(left < len && arr[left] > arr[largest]) {
        largest = left
    }
    if(right < len && arr[right] > arr[largest]) {
        largest = right
    }
    // 排除根节点
    if(largest != i) {
        // 如果子节点最大,则调换位置
        let temp = arr[i]
        arr[i] = arr[largest]
        arr[largest] = temp
        // largest 变为子节点
        heapFy(arr, largest)
    }

}

效率测试:千万数组

在这里插入图片描述

归并排序算法

通过递归,将每一个传入的数组依次分成2个子序表,这2个子序表分别比较大小,并按照比较结果保存到新的数组里面,最后归并

有点将数组拆分成2个单位的数组进行比较,分成最小的模块最后再一起重新合并比较

在这里插入图片描述

function mergeSort(arr) {
    let length = arr.length
    if(length<2) return arr
    var middle = Math.floor(length / 2)
    // 一分为2 
    var left = arr.slice(0,middle)
    var right = arr.slice(middle)
    return merge(mergeSort(left),mergeSort(right))
}
function merge(left, right) {
     // 保存结果
     var result = []
     while(left.length > 0 && right.length > 0) {
         if (left[0] <= right[0]) {
             // 保存left[0]
             result.push(left.shift())
         } else {
             result.push(right.shift())
         }
     }
    // 多余的left或者right直接合并
     if(left.length) {
        result= result.concat(left)
     }
     if(right.length) {
        result = result.concat(right)
     }
     return result
}

效率测试:1百万数组
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值