Java面试必备--经典代码回顾(一)

     相信很多同行小伙伴会因为许多原因想跳槽,不论是干得不开心还是想跳槽涨薪,在如此内卷的行业,我们都面临着“面试造火箭,上班拧螺丝”的局面,鉴于当前形势博主呕心沥血整理的干货满满的造火箭的技巧来了,本博主花费2个月时间,整理归纳java全生态知识体系常见面试题!总字数高达百万! 干货满满,每天更新,关注我,不迷路,用强大的归纳总结,全新全细致的讲解来留住各位猿友的关注,希望能够帮助各位猿友在应付面试笔试上!当然如有归纳总结错误之处请各位指出修正!如有侵权请联系博主QQ1062141499!
 


目录

1 JAVA中数组扩容的三种方式

2  冒泡排序(Bubble Sort)

3 插入排序(Insertion Sort)

4 选择排序(Selection Sort)

5 希尔排序(Shell Sort)

6 递归阶乘

7 ​​​​​​使用递归输出某个目录下所有子目录和文件


1 JAVA中数组扩容的三种方式

 ①    int[] arr2=new int[arr1.length*2]   //新数组长度
        for(int i=0;i<arr1.length;i++){     //复制
            arr2[i]=arr1[i];
        }
 ②    int[] arr2=java.util.Arrays.copyOf(原数组名,新数组长度);
 ③    int[] arr2=new int[arr1.length*2]
        System.arraycopy(原数组名,起始下标,新数组名,起始下标,复制长度);

2  冒泡排序(Bubble Sort)

       冒泡排序是一种简单的排序算法。

步骤:

  1. 遍历比较相邻的两个元素,被比较的左边元素大于右边元素,则交换位置。第一轮遍历、比较、交换完,最后一个是最大的元素
  2. 若本次遍历中没有数据交换,代表排序结束,提前退出
  3. 有数据交换则再从第一个元素开始遍历、比较、交换,排除最后一个元素
  4. 重复 1、2、3 步骤,每次排除上次被遍历的最后一个元素,直到排序完成
 public static void main(String[] args) {
        int[] ints = {3, 4, 23, 11, 0, 3, 4};
        bubbleSort(ints);
    }
    /**
     * 冒泡排序算法
     * 只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。
     * 如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复n 次,
     * 就完成了 n 个数据的排序工作。
     **/
    private static void bubbleSort(int[] ints) {
        //临时交换的数据
        int temp;
        for (int i = 0; i < ints.length; i++) {
            //j<ints.length-i-1,因为冒泡是把每轮循环中较大的数飘到后面
            for (int j = 0; j < ints.length - i - 1; j++) {
                if (ints[j] > ints[j + 1]) {
                    temp = ints[j];
                    ints[j] = ints[j + 1];
                    ints[j + 1] = temp;
                }
            }
            System.out.println(Arrays.toString(ints));
        }
    }

打印结果:

[3, 4, 11, 0, 3, 4, 23]
[3, 4, 0, 3, 4, 11, 23]
[3, 0, 3, 4, 4, 11, 23]
[0, 3, 3, 4, 4, 11, 23]
[0, 3, 3, 4, 4, 11, 23]
[0, 3, 3, 4, 4, 11, 23]
[0, 3, 3, 4, 4, 11, 23]

3 插入排序(Insertion Sort)

思路:

  • 将数组分为两个区域:已排序、未排序。
  • 初始已排序区域只第一个元素
  • 取未排序的区域的元素,在已排序的区域找到合适的位置插入
  • 保证已排序区域的数据一直有序
  • 重复这个过程,直到未排序区域为空

步骤:

  • 从数组第二个数开始,往后逐个取数,跟前面的数进行比较
  • 当所取的数,比前面的数大,停止比较,取一下个进行比较
  • 当所取的数,比前面的数小,把比所取数大的数都往后挪一个,直到所取数大于被比较的数停止,最后把所取数插入到比它小的数的右边

代码:

public static void main(String[] args) {
        int[] ints = {3, 4, 23, 11, 0, 3, 4};
        insertionSort(ints);
    }
    /**
     * 插入排序
     */
    private static void insertionSort(int[] ints) {
        for (int i = 1; i <ints.length; i++) {
            int j = i - 1;
            int value = ints[i];
            for (; j >= 0; j--) {
                if (ints[j] > value) {
                    ints[j+1] = ints[j];
                } else {
                    break;
                }
            }
            ints[j+1] = value;
            System.out.println(Arrays.toString(ints));
        }
    }
}

打印

[3, 4, 23, 11, 0, 3, 4]
[3, 4, 23, 11, 0, 3, 4]
[3, 4, 11, 23, 0, 3, 4]
[0, 3, 4, 11, 23, 3, 4]
[0, 3, 3, 4, 11, 23, 4]
[0, 3, 3, 4, 4, 11, 23]

特征:

  • 最好情况时间复杂度:O(n) 。即数组本身有序,如 1,2,3,4,5
  • 最坏情况时间复杂度:O(n2) 。即数组本身完全逆序,如 5,4,3,2,1
  • 平均时间复杂度:O(n2) 。在数组中插入一个数据的平均时间复杂度是 O(n),插入排序执行 n 次往数组中插入操作,所以平均时间复杂度是 O(n2)
  • 空间复杂度是 O(1)。是原地排序
  • 可以保持相等的值原有的前后顺序不变,是稳定排序

4 选择排序(Selection Sort)

思路:

  • 数组区分已排序区域和未排序区域
  • 每次从未排序区域找到最小的元素,通过和未排序区域第一个元素交换位置,把它放到已排序区域的末尾

步骤:

  • 进行 数组长度-1 轮比较
  • 每轮找到未排序区最小值的小标
  • 如果最小值的下标非未排序区第一个,进行交换。此时未排序区第一个则变为已排序区最后一个
  • 进行下一轮找未排序区最小值下标,直到全部已排序

代码:

public static void main(String[] args) {
    int[] ints = {3, 4, 23, 11, 0, 3, 4};
    selectionSort(ints);
}
/**
 * 选择排序
 */
public static void selectionSort(int[] ints) {
    //进行 数组长度-1 轮比较
    int minIndex;
    for (int i = 0; i < ints.length - 1; i++) {
        minIndex = i;//取未排序区第一个数的下标
        for (int j = i + 1; j < ints.length; j++) {
            if (ints[j] < ints[minIndex]) {
                //找到未排序区域最小值的下标
                minIndex = j;
            }
        }
        //找到的最小值是否需要挪动
        if (i != minIndex) {
            int temp = ints[i];
            ints[i] = ints[minIndex];
            ints[minIndex] = temp;
        }
        System.out.println(Arrays.toString(ints));
    }
}

打印

[0, 4, 23, 11, 3, 3, 4]
[0, 3, 23, 11, 4, 3, 4]
[0, 3, 3, 11, 4, 23, 4]
[0, 3, 3, 4, 11, 23, 4]
[0, 3, 3, 4, 4, 23, 11]
[0, 3, 3, 4, 4, 11, 23]

特征:

  • 空间复杂度为 O(1),是原地排序算法
  • 最好情况时间复杂度为 O(n2)。即使是有序数组,也需要经过 n-1 轮找未排序区最小值下标
  • 最坏情况时间复杂度为 O(n2)
  • 平均情况时间复杂度为 O(n2)
  • 非稳定排序,即排序后不能保证两个相等值的前后顺序未变。如:4,8,4,2,9。第一轮找到最小元素 2,跟第一个 4 交换位置,直到排序完成第一个 4 排在第二个 4 后面

5 希尔排序(Shell Sort)

       插入排序经过改进之后的高效版本,也称缩小增量排序。1959 年提出,是突破时间复杂度 O(n2) 的第一批算法之一。缩小增量排序的最优增量选择是一个数学难题,一般采用希尔建议的增量,具体如下。

思路与步骤:

  • 首次选择的增量(即步长,下同) step = 数组长度 / 2 取整;缩小增量 step​ ,每次减半,直到为 1 结束缩小;逐渐缩小的增量组成一个序列:[n/2, n/2/2, ... 1]
  • 对数组进行 序列里增量的个数 趟排序
  • 每趟排序,把增量作为间隔,将数组分割成若干子数组,分别对各子数组进行插入排序
  • 当增量等于 1 时,排序整个数组后,排序完成

代码:

public static void main(String[] args) {
    int[] ints = {3, 4, 23, 11, 0, 3, 4};
    selectionSort(ints);
}
/**
 * 希尔排序
 */
private static void shellSort(int[] ints) {
    int length = ints.length;
    int step = length / 2; //步长,默认取数组长度一半
    int temp;
    while (step > 0) {
        for (int i = step; i < length; i++) { //从步长值为下标,开始遍历
            temp = ints[i]; //当前值
            int preIndex = i - step; //步长间隔上一个值的下标
            //在步长间隔的的数组中,找到需要插入的位置,挪动右边的数
            while (preIndex >= 0 && ints[preIndex] > temp) {
                ints[preIndex + step] = ints[preIndex];
                preIndex -= step;
            }
            //把当前值插入到在步长间隔的的数组中找到的位置
            ints[preIndex + step] = temp;
        }
        step /= 2;
        System.out.println(Arrays.toString(ints));
    }
}
打印
[3, 0, 23, 6, 4, 33, 11]
[0, 3, 4, 6, 11, 23, 33]

特征:

  • 空间复杂度为 O(1),是原地排序算法
  • 最好、最坏、平均情况时间复杂度,都是 O(nlog2 n)
  • 非稳定排序。因为进行了增量间隔分组排序,可能导致相等的值先后顺序变换

6 递归阶乘

n!=1×2×3×...×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。

亦即n!=1×2×3×...×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。

如5的阶乘为1*2*3*4*5=120,用代码实现如下:

public static void main(String[] args) {
    System.out.println(recursionN(5));
}
/**
 * 递归计算n的阶乘
 * @param n
 * @return
 */
private static int recursionN(int n) {
    if (n <1) {
        throw new IllegalArgumentException("参数必须大于0");
    } else if (n == 1) {
        return 1;
    } else {
        return n * recursionN(n - 1);
    }
}

7 ​​​​​​使用递归输出某个目录下所有子目录和文件

public static void main(String[] args) {
    print(new File("E:/"));
}
private static void print(File file) {
    System.out.println(file.getAbsolutePath());
    if (file.isDirectory()) {
        File[] files = file.listFiles();
        for (File f : files) {
            print(f);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值