ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

线性查找法02:循环不变量和算法复杂度

2021-09-27 19:01:50  阅读:103  来源: 互联网

标签:02 arr int 复杂度 ++ 查找 Integer 循环


循环不变量

public static<E> int search(E[] arr, E target){
    /**
     * 循环不变量,就是在循环中始终遵守的原则
     * 因为在arr[0...i-1]中没有找到目标,所以才继续循环
     * 这个arr[0...i-1]就是循环不变量,在写循环时一定要清楚循环不变量是什么
     */
    for (int i = 0; i < arr.length; i++) {
        /**
     	 * 循环体就是为了维持循环不变量,证明算法的正确性
    	 */
        if (target == arr[i]) {
            return i;
        }
    }
    return -1;
}

算法复杂度

复杂度描述的是随着数据规模n的增大,算法性能的变化趋势

在复杂度分析中,常数不重要(线性查找法的复杂度是O(n))

T1 10000n O(n)
T2 2n^2 O(n^2)
当n > 5000,T2复杂度大于T1,并且规模越大,差距越大

常见的时间复杂度

/**
 * 遍历一个n*n的二维数组,n指维度,复杂度是O(n^2)
 */
for (int i = 0; i < n; i++){
    for (int j = 0; j < n; j++){
        return arr[i][j];
    }
}

/**
 * 遍历一个a*a的二维数组,其中a*a=n,n指元素总数,复杂度是O(n)
 * 因此一定要清楚n到底指的是谁
 */
for (int i = 0; i < a; i++){
    for (int j = 0; j < a; j++){
        System.out.println(arr[i][j]);
    }
}

/**
 * 输出数字num的二进制位数,n和要计算的次数有关,每计算一次,规模除以2,复杂度是O(logn)
 * 对log函数而言,底数不同相差的是常数,因此忽略底数
 */
while (n){
    System.out.println(num % 2);
    num /= 2;
}

/**
 * 输出数字num的约数,约数是成对出现的,只要循环到根号num就可以拿到所有约数,因此n指根号num
 * 复杂度是O(sqrt{n})
 */
for (int i = 1; i * i <= n; i++) {
    if (n % i == 0){
        System.out.println(i);
        System.out.println(n / i);
    }
}

/**
 * 输出长度为n的二进制数字,每增加一个长度,规模翻倍,复杂度是O(2^n)
 */

/**
 * 输出长度为n的数组的全排列,复杂度是O(n!)
 */

/**
 * 判断数字n是否是偶数,只用执行常数量级的语句,复杂度是O(1)
 */

总结:O(1) < O(logn) < O(sqrt(n)) < O(n) < O(nlogn) < O(n^2) < O(2^n) < O(n!)

测试线性查找算法性能

public class Algorithm {

    public static void main(String[] args) {

        Integer n = 10000000;
        Integer[] arr = ArrayGenerator.generatorArray(n);
        Integer target = n;

        /**
         * System.nanoTime()方法打印时间戳
         */
        long startTime = System.nanoTime();

        /**
         * 循环多次测试时间性能,比一次性测试更稳定,结果也更真实
         */
        for (int i = 0; i < 100; i++) {
            LinerSearch.search(arr, target);
        }

        long endTime = System.nanoTime();
        System.out.println((endTime - startTime) / 1000000000.0 + "秒");
    }
}

class LinerSearch {

    private LinerSearch(){}

    public static<E> int search(E[] arr, E target){
        for (int i = 0; i < arr.length; i++) {
            if (arr[i].equals(target)) {
                return i;
            }
        }
        return -1;
    }
}

/**
 * 创建一个根据n生成数组的类
 */
class ArrayGenerator {
    private ArrayGenerator(){}

    public static Integer[] generatorArray(Integer n){

        Integer[] arr = new Integer[n];

        for (int i = 0; i < n; i++) {
            arr[i] = i;
        }
        return arr;
    }
}

标签:02,arr,int,复杂度,++,查找,Integer,循环
来源: https://www.cnblogs.com/taoyuann/p/15344297.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有