首页 > 编程语言 >复杂度分析、排序算法、二分法、堆的上调和下调

复杂度分析、排序算法、二分法、堆的上调和下调

时间:2022-08-22 17:26:28浏览次数:70  
标签:arr return int 复杂度 二分法 midIndex heap 排序

1.认识复杂度与排序算法

  1. 复杂度:认识时间复杂度就是看进行了多少次常数操作。(什么是常数操作?赋值、加减乘除运算等都是。调用API操作就不是如list.get(i)。)

    • 时间复杂度:在常数操作的数量级表达式中不要低阶项,只要最高阶项,并忽略系数。
    • 空间复杂度:系统需要额外空间去保存变量。
  2. 选择排序:

    • 概念:一个n长度的数组,从0-n-1找最小的数,然后和第一个数交换,第一个数不动。再从1-n-1找最小的数,然后和第二个数交换,第二个数不动,依次查找。

    • 时间复杂度分析:若时间复杂度指标相同,可以实际测试来看那个好。O(n^2)

    • 空间复杂度分析:看代码,minIndex每次进入循环都重新申请,完了又释放,所以复杂度为O(1)

    • 代码框架:

      public static void selectionSort(int[] arr){
          int len = arr.length();
          if(arr == null || len < 2)
              return;
          for(int i=0;i<len-1;i++){
              int minIndex = i;
              for(int j=i+1;j<len;j++){
                  minIndex = arr[j] < arr[minIndex] ? j : minIndex;
              }
              swap(arr,i,minIndex);//把找到的最小值和第一个数交换
          }
      }
      
  3. 冒泡排序:

    • 概念:相邻两个比较,大的往后排,第一轮找到最大的,第二轮找到次大的,依次.....

    • 时间复杂度分析:O(n^2)

    • 空间复杂度分析:对arr数组中的每个数进行比较,申请了空间为n的数组,则O(n)

    • 代码框架:

      public static void bubbleSort(int[] arr){
          if(arr == null || arr.length() < 2)
              return;
          for(int i=0;i<n-1;i++){
              for(int j=0;j<n-i-1;j++){
                  if(arr[j]>arr[j+1])
                      swap(arr[j],arr[j+1]);
              }
          }
      }
      
  4. 异或^

    • 概念:相同的为0,不同的为1。也可理解为无进位相加,1+0=1,1+1=2,不进位后,1+1=0。

    • 性质:

      • a^a = 0,a^0 = a
      • 满足交换律、结合律
    • 举例运算:

      public static void swap(int a,int b){
          a = a^b;
          b = a^b;
          a = a^b;
          //完成交换
      }
      

    • 例子:可以求一个数组中出现奇数次的数。(全部异或)
  5. 插入排序

    • 概念:一个数组a[n],①先看0-0区间,已经排序;②看0-1区间,如果a[1]<a[0],就交换两个数,排好序;③看0-2区间,a[2]依次与前面的那个数比较。

    • 时间复杂度分析:最差情况下,如【1,2,3,4,5,6,7】每一次都要与前面交换i次,因此表达式为1+2+3+...+n,则时间复杂度为O(n2)。最好情况下,如【5,4,3,2,1】,每一次都只需要看前面一眼,因此为O(n)。所以插入排序时间复杂度为O(n2)

    • 代码框架:

      public static void insertSort(int[] arr){
          if(arr == null || arr.length() < 2)
              return;
          for(int i=1;i<arr.length();i++){
              for(int j=i-1;j>=0;j--){
                  if(arr[j]>arr[j+1])
                      swap(arr,j,j+1);
              }
          }
      }
      
  6. 二分查找

    • 时间复杂度:O(logN),每一次都砍一半。

    • 代码框架:

      public static int twoSort(int[] arr,int i,int j){
          int midIndex = (i+j)/2;
          if(arr[midIndex] == num)
              return midIndex;
          if(arr[midIndex] > num)
              twoSort(arr,midIndex+1,n);
          else
              twoSort(arr,0,midIndex-1);
          return midIndex;
      }
      

2.堆

  1. 上调:

    • 应用:堆的初始化、向堆中添加一个元素

    • 过程:

    • 代码:

      #include <iostream>
      #include <vector>
      using namespace std;
      
      vector<int> heap;//存储堆
      vector<int> index;
      
      /**上调
       **参数:位置i
      **/
      void shiptUp(int i){
          if(i==1)
              return ;
          int flag=0;  //标记是否需要交换
          while(i!=1 && flag==0){
              if(heap[i] < heap[i/2])
                  swap(heap[i],heap[i/2]);
              else
                  flag=1;
              i/=2;
          }
      }
      
      int main(){
          //题目给出一个数组,要建成小顶堆
          int n;
          for(int i=1;i<=n;i++){
              cin>>heap[i];
              shiftUp(i);  
          }
          return 0;
      }
      
  2. 下调

    • 应用:用某数替换最小值/最大值(根)。

    • 过程:

    • 代码:

      //大顶堆
      
      #include <iostream>
      #include <vector>
      using namespace std;
      
      vector<int> heap;//存储堆
      vector<int> index;
      
      /**上调
       **参数:位置i
      **/
      void shiftDown(int i){
          int flag=0,t;
          while(i*2<n&&flag==0){//如果有左孩子,左孩子比根大,则要考虑根左孩子换
              if(heap[i]<heap[i*2])
                  t=i*2;
              else
                  t=i;
              if(i*2+1<n){//如果有右孩子,右孩子比左孩子还大,则要根右孩子换
                  if(heap[t]<heap[i*2+1])
                      t=i*2+1;
              }
              //如果发现t不是自己
              if(i!=t){
                  swap(heap[i],heap[t]);
                  i=t;
              }else{
                  flag=1; //不用换
              }
          }
      }
      
      int main(){
          int n;
          shiftDown(0); //根节点位置为0
          return 0;
      }
      

      注:小顶堆只需要将heap[i] < heap[i2] 改为heap[i] >heap[i2](包含右孩子比较的)即可。

标签:arr,return,int,复杂度,二分法,midIndex,heap,排序
From: https://www.cnblogs.com/lxpblogs/p/16613478.html

相关文章

  • java算法:快速排序
    快速排序有没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”啦!光听这个名字是不是就觉得很高端呢。假设我们现在对“61279345108”这个10个数进行......
  • Mysql Order By 字符串排序,1 10 2 20,以字符串排序,不是使用数字排序
    一、问题描述:Mysql排序时如果用的的字段为字符串型的,排序规则是这样的:如1,10,2,20,3,4,5,这种排序是按照字符从第一个字符开始比较出来的,但不是我想要的,我想要的是:1,2,3,4,5……,10,20......
  • 归并排序
    1.归并排序——分治#算法原理归并排序的思想就是分治,先递归分解数组,再合并数组。将数组分解到最小之后,再往上一层两两合并两个有序的数组,最终递归返回的就是一个排好......
  • AcWing算法基础课---第一讲基础算法---01排序
    快速排序步骤确定分界点:q[l],q[(l+r)/2],q[r],随机调整区间递归处理voidquick_sort(intq[],intl,intr){if(l>=r)return;//递归结束条件......
  • 分页和排序
    分页和排序排序--排序:升序asc,降序desc--orderby通过哪个字段排序,怎么排--查询的结果根据成绩降序排序SELECTs.`studentno`,`studentname`,`subjectname`,......
  • Mysql-排序与分页
    1.排序使用orderby进行排序:ASC(ascend)升序,DESC(descend)降序,一般把orderby语句放在select语句的结尾,多列排序的顺序按照orderby后的字段顺序进行......
  • 字典排序
    importoperatordefdeal_dict_sort():x=[{'name':'Homer','age':39},{'name':'Bart','age':10}]lx=sorted(x,key=operator.itemgetter('age'),......
  • 二叉排序数
    1.为什么要用二叉排序树使用数组数组未排序,优点:直接在数组尾添加,速度快。缺点:查找速度慢.数组排序,优点:可以使用二分查找,查找速度快,缺点:为了保证数组有序,在添加新数据......
  • 二分法查找
    importrandomclassSearch(object):defbinary_search(self,data,value):"""二分查找迭代法实现:paramdata:list待查找序列......
  • 2022-8-20 剑指offer-滑动窗口+(桶排序或者有序集合)
    剑指OfferII057.值和下标之差都在给定的范围内难度中等55收藏分享切换为英文接收动态反馈给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在......