排序算法

平时不常用,面试会问,做理解记录;还有种一看就懂,不看就忘的错觉。

排序算法归类:

算法思想性能分类
冒泡排序时间复杂度O(n^2) 空间复杂度O(1)交换排序
快速排序事件复杂度O(nlbn) 空间复杂度O(n)交换排序
选择排序时间复杂度O(n^2) 空间复杂度O(1)选择排序
堆排序选择排序
插入排序时间复杂度O(n^2) 空间复杂度O(1)插入排序
希尔排序插入排序
冒泡排序

基本思想:内部for循环中j+1j进行比较,可交换则进行值交换,此时置flag为true,n-1次循环结束后把最大的值交换到了最后,则下次循环n-2(因为i++);将第二大数值、第三大数值…排到后第二、三位…最终完成arr[0]arr[0]的比较,完成排序。

说明:flag用于提前返回,减少内部for循环;如果第一次n-1次循环结束没有发生交换,说明当前数组是排序好的。则无需再循环处理, 直接返回。

// 这是我印象中一直存在的
function BubbleSort(arr){
    let len = arr.length;
    for(let i=0;i<len-1;i++){
        for(let j=i+1;j<len;j++){
            if(arr[i]>arr[j]){
                [arr[i],arr[j]] = [arr[j],arr[i]]
            }
        }
    }
    return arr;
}
// 这是一个变种,优点是如果排序好的话,不在处理。
function BubbleSort(arr){
  let len = arr.length;
  let flag = true;      // 标识是否进行了值交换
  for(let i=1;i<len&&flag;i++){       // 根据判断 flag; 如果没有交换过值,则当前数组是排序好的,
    flag = false;
    for(let j=0;j<len-i;j++){       // 内存循环依次把最大的值交换到最后
      if(arr[j]>arr[j+1]){
        flag = true;                   
        [arr[j],arr[j+1]] = [arr[j+1],arr[j]];
      }
    }
  }
  return arr;
}
快速排序

快速排序是一种二叉树结构的交换排序算法。递归

思想:

  • 选取一个元素作为基准,比这个数小的放左边,比这个数大的放右边。
  • 左边的数再选取一个元素作为基准,重复上述一步骤。
  • 右边的数再选取一个元素作为基准,重复上述一步骤。

说明:
  以temp(arr[low]) 为基准元素,第一个while循环查找比temp小的值,j最小为i;如果存在这个值,给当前i位置赋值,这是第一个小于基准值temp的值,放到了左边;第二个while循环查找比temp大或相等的值,i最大为j;如果这个值存在,给当前的位置j赋值,即把比temp大的值放到了右边; 继续循环条件i<j ;
  整个while(i<j)循环结束后,基准值temp左边是比它小的,右边是比它大的;i的位置即是基准值。

function QuickSort(arr,low=0,high=arr.length-1){
  let i = low,j = high;
  let temp = arr[low];
  while(i<j){                 // 依次循环结束标识,i>=j
    while(i<j&&temp<=arr[j]){        // 找到比temp 小的值,j最小为i
      j--;
    }
    if(i<j){       // j 不等于i ,找到了比temp 小的值,进行值交换
      arr[i] = arr[j];     // i 的位置则放置为更小的值
      i++;
    }
    while(i<j&&arr[i]<temp){    // 找temp 大或相等的值,i最大为 j 
      i++;
    }
    if(i<j){          // i 不等于j ,找到了比temp大的值,进行值交换
      arr[j] = arr[i];
      j--;
    }
  }
  arr[i] = temp;
  if(low<i) QuickSort(arr,low,i-1);
  if(i<high) QuickSort(arr,j+1,high);
  
  return arr;
}
选择排序

思想:

  • 假设minIndex = i下标值为最小值,则从j = i+1起其他位置找比它小的值,记录下标值minIndex

  • minIndex != i时,有最小值,进行交换。

  • 直到循环结束

    按最从小到大排列:

function SelectSort(arr){
  let minIndex=0,
    len = arr.length;                               
  for(let i=0;i<len-1;i++){
    minIndex = i;                          // 默认最小值的下标值为 i ,找比它小的值得下标      
    for(let j=i+1;j<len;j++){
      if(arr[minIndex]>arr[j]){                     // 找到比i 位置小的值,记录下标值
        minIndex = j; 
      }
    }
    if(minIndex!=i){                               // 最小值小标不等于i  时,进行交换
          [arr[i],arr[minIndex]] = [arr[minIndex],arr[i]];
       }
  }
}
插入排序

思想:

  • 假设arr[i]是最小的,判断arr[i+1]是不是更小,则进行交换;
  • 已经排好两个,进行下次循环i++,此时i=1;需要查找的是arr[0]、arr[1]、arr[2],将arr[2]交换到合适的位置;
  • ...
function InsertSort(arr){
  let len = arr.length;
 for(let i=0;i<len-1;i++){
   let j= i;
   temp = arr[i+1];
   while(j>-1 && temp<arr[j]){
     arr[j+1] = arr[j];
     j--;
   }
     arr[j+1] = temp;
 }
 return arr;
}
希尔排序

在分组中实现的插入排序。把待排数据分为若干小组,在各小组内实现插入排序,减少分组继续排序。

堆排序

将待排序的数据元素构成一个完全二叉树结构,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heroboyluck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值