什么是算法与数据结构?

算法 就是你设计一些功能 要完成一些流程 设计流程本身就是算法 有时候是做1个处理 有时候是返回1个信息 需要设计流程
有些算法 会使用到一些数据结构 有些数据结构是专门适用于一些算法的 专门为了加速算法或者让算法的流程变得更好 但是 数组以及二叉树结构 它们是专属于某个算法吗? 不是 它就是用来组织数据的结构 是数据结构

算法评估的指标:
第一是 时间复杂度
第二是 额外空间复杂度
第三是 常数项时间
分别介绍一下
常数时间的操作:



比如 你把数组上第100位的数拿出来 以及你把第10000位的数拿出来 时间 不会因为你传进来的 1千 1千亿而有差别 因为内部是直接寻址实现 不是一步一步遍历 去拿到那个值的 所以数组的寻址操作 就是1个固定时间的操作 它和数据量无关 每次时间都固定下来 相反的是链表


常见的常数时间操作

注意*和/也算是常数时间的操作哦
非常数时间的操作,比如linkedlist的list.get(i)不是常数时间的操作 它要从前面一直数到i 返回 它是通过指针指的 不是1个连续空间 在内存是分散的

时间复杂度:
比如1个选择排序的过程:
1.下标0到N-1 先把最小的数找到 然后把它和0位置交换一下 0位置的数搞定了
2.然后 1到N-1上再找 这个范围的最小值 然后再和1位置的数交换
3.重复玩这件事


那么这个操作 发生了多少次常数时间操作?
0到N-1可能每个数都要看一下 看的时候 要和之前已经 找到的最小值 做比较
看 就是数组寻址 把数拿出来 和之前找到的最小值比较 如果它更小 我们要记录它的位置
每个位置 0-N-1我们进行 N-1次看+比
然后 过完这些数之后 我们单独做1次交换操作

所以全部加起来


时间复杂度 就是看它增长最大的项 它只关心它的量级 而不是数量级 数量级是以10为底的

排序算法代码

public static void selectSort(int[] arr){
        if(arr == null || arr.length < 2){
            return;
        }
        for (int i = 0;i<arr.length;i++){
            /**
             * 与其去记录最小值 不如记录最小值坐标minIndex
             * 因为最小值可能在数组中有相等的 但是每个坐标一定是独一无二的
             * 虽然记录值的方法也可以 但是对于对象就失效 如果你要比较的是
             * 对象中的某个值 你再记录值对于对象的排序是没有用
             * 对象的排序是需要的是地址 即坐标
             */
            int minIndex = i;
            for(int j=i+1;j<arr.length;j++){
                //一行代码 三元表达式 寻找最小坐标
                minIndex =(arr[j] < arr[minIndex]) ? j : minIndex;
            }
            //交换最小值坐标和当前遍的首坐标 降序排序
            swap(arr,i,minIndex);
        }
    }

public  static void  swap(int[] arr,int i, int j){
        /**
         * 此swap实现的只是 简单的值传递
         * 如果涉及到对象的地址传递 则会出错
         */
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;

    }

public static int[] generateRandomArray(int maxSize,int maxValue){
        /**
         * 产生一个最大范围内大小的数组(int)((maxSize+1) * Math.random())
         * 为什么maxSize和maxValue都要+1
         * 因为1.Math.random()产生的数在[0,1)之间
         * 2.java的强制类型转化(int)是向下转化的 即1.9->1 1.9999->1
         * 所以要+1
         */
        int[] arr =new int[(int)((maxSize+1) * Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)((maxValue+1) * Math.random()) - (int)((maxValue+1) * Math.random());
        }
        return arr;
    }

public static void main(String[] args) {
        int[] arr = generateRandomArray(50,50);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        selectSort(arr);
        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }

    }
selectSort测试

有了对数器 你不再依赖 1个题目在线测试的页面 自己就可以改出万无一失的代码 两套思路 两套方法 因为样本产生器是可以控制大小 当它错误时 打印出错误信息 通过断点调试的方法 看1个个的值的变化 人肉的把它调对
实现对数器 需要前面的generatorRandomArray方法
还需要自己写一个copyArray数组方法 来拷贝两个数组 同时跑两个方法 来比较

public static int[] copyArray(int[] arr){
        if(arr == null){
            return  null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i]
        }
        return res;
    }

还需要一个方法来判断两个数组是否相等的 isEquall

public static boolean isEqual(int[] arr1,int[] arr2){
        if ((arr1 == null && arr2 !=null)||(arr1 !=null && arr2 == null)) return  false;
        if((arr1 == null) && (arr2 ==null))return true;
        if(arr1.length!=arr2.length)return false;
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]){
                return false;
            }
        }
        return true;
    }

因为我们使用系统实现的排序来进行对照 所以要实现1个comparator接口

public static void comparator(int[] arr){
        Arrays.sort(arr);
    }
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]+' ');
        }
    }

然后对数器 真正实现在main方法中

public static void main(String[] args) {
        final int TESTTIME = 500000;
        final int MAXSIZE = 100;
        final int MAXVALUE = 100;
        boolean succeed = true;
        for (int i = 0; i < TESTTIME; i++) {
            int[] arr1 = generateRandomArray(MAXSIZE,MAXVALUE);
            int[] arr2 = copyArray(arr1);
            selectSort(arr1);
            comparator(arr2);
            if (!isEqual(arr1,arr2)){
                succeed = false;
                printArray(arr1);
                printArray(arr2);
                break;
            }
        }
        System.out.println(succeed?"Nice!":"Fucking failed");
    }

测50w次TESTTIME=5000000 只要错一点 屎都给你测出来



实现1个对数器
包括 1.实现两个效果一样的方法 2.实现1个随机数产生数组 3.对两个方法的结果 进行验证错误 4.排错 这4个步骤 但有些题 是不需要3步骤的 比如找到1个数 根据题目情况而定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值