DAY1 数据结构与算法

·一、位运算
1. int类型的数据在大多数语言中,以32位的二进制数表示。
2. 设计一个函数,以打印int类型的二进制形式,思路如下:
循环遍历整数的32位(即从31到0),对于每一位执行以下操作:
使用位运算符 “&” 将当前位与二进制掩码 1 << i 进行按位与运算。这将保留当前位的值并清除其他位上的值。
检查当前位的值。如果它为0,则输出"0";否则,输出"1"。
重复上述步骤,直到所有位都被处理完毕。
 

public static void print(int num){//输出int类型的二进制形式
    for (int i = 31; i >=0 ; i--) {
        System.out.print((num&(1<<i))==0?"0":"1");
    }
    System.out.println();
}

为什么遍历时,是从31位到0位,而不是从0位到32位?

**答:**在输出时,是从左到右依次输出每一位的值,因此最低位(即二进制数的最右边一位)输出在了最前面,而最高位(即二进制数的符号位,如果是负数则为 1)输出在了最后面。因此,这种输出方式会得到二进制数的反向输出结果。如果想要正常输出二进制数,需要将循环的处理顺序从第 31 位到第 0 位进行。

3. 关于int类型的数据,在C++当中为无符号数,而在Java当中为有符号数,因此:
在C++当中,int能表示的数值的范围为:0~2^32-1;

而在Java中,因为有符号位(符号位为1表示负数),所以int能表示的数值的范围为:-231~231-1;

关于负数:第32位必为1,其余31位取反再+1即为负数绝对值(正负转换都是:~a+1);

⚠️所有正数都有负数对应,但是系统最小的负数取反加一还是自己;

左移:<< 最后一位补零 右移:>> 不带符号(符号位补0) >>>带符号(符号位不动,其余右移)。
 

System.out.println("2⃣️查看Java中int的最大最小值:");
      int max=Integer.MAX_VALUE;
      int min=Integer.MIN_VALUE;
      System.out.println(max);
      System.out.println(min);
      print(max);
      print(min);
      print(-1);

      System.out.println("3⃣️️验证与非或运算:");
      int a = 12319283;
			int b = 3819283;
			print(a);
			print(b);
      print(~b);
System.out.println("=============");
print(a | b);
print(a & b);
print(a ^ b);//抑或:不同为1,相同为0

二、算法
1.定义
1)有具体的问题
2)有设计解决这个问题的具体流程
3)有评价处理流程的可量化指标
2.分类
1)明确知道怎么算的流程
2)明确知道怎么试的流程
三、阶乘的算法(给定一个参数N,返回1!+2!+3!+…+N!的结果)
1.解法一
老老实实算每个阶乘然后加起来:1!+2!+3!+…+n!

2.解法二
每次用上次得到的乘积再乘上这次的新数字再相加:1!+1!×2+2!×3+…+(n-1)!×n
 

public static long SOF(long n){
    long sum=0;
    long ans=1;
    for (long i = 1; i <=n; i++) {
        ans*=i;
        sum+=ans;
    }

    System.out.println(ans);
    System.out.println(sum);
    return sum;
}

四、三种经典排序

1.选择排序(Selection Sort)

  • 在全部数字当中,挑选最小的数,推到第一位

  • 然后总长度-1,在剩下的数当中挑选,再补到目前的第一位(总长度的第2位)以此类推

  • public static void selectSort(int[] arr){//选择排序主体
        if(arr==null || arr.length<2){
            return ;
        }
        for (int i = 0; i < arr.length; i++) {//i的值代表从左到右
            int minIndex=i;//默认i是最小值
            for (int j = i+1; j < arr.length; j++) {//从i的右边开始遍历
                minIndex= arr[j]<arr[minIndex]? j : minIndex ;//锁定i后方的最小值的下标
            }
            swap(arr,i,minIndex);//交换到最前面i的位置
        }
    }
    

    2.冒泡排序(Bubble Sort)

  • 两两比较,每次只和相邻位置的数比大小

  • 按大小更换左右位置,然后向后推进

  • 当推到最后一位时,重回第一位开始比较

  • public static void bubbleSort(int[] arr){
        if(arr==null || arr.length<2){
            return ;
        }
        for (int i = arr.length-1; i >0 ; i--) {//每次循环冒泡完最大值都在最右边,所以每次范围从右向左-1
            for (int j = 0; j < arr.length-1; j++) {//从左往右冒泡的过程
                if (arr[j]>arr[j+1]){//如果大,就交换
                    swap(arr,j,j+1);
                }
            }
        }
    }
    

    3.插入排序(Insertion Sort)

  • 第一次前两个排序,第二次前三个排序,以此类推

  • 在排序的过程中,将每次新加入的数字按大小顺序插入到前几位已经排好的数当中,以此类推

  • 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 && arr[j+1]<arr[j]; j--) {
                swap(arr,j,j+1);
              //注意,此处是j+1而不是i,因为在每一次的循环中,i是固定的,代表右边界。而j的值每次向左递减
            }
        }
    }
    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值