Java基础-时间复杂度计算方式
Java基础-时间复杂度计算方式
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
时间复杂度通常是衡量算法的优劣的,衡量算法的时间严格来讲是很难衡量的,由于不同的机器性能不用环境都会造成不同的执行时间。
一.什么是时间复杂度
1>.什么是时间频度
算法的执行时间和语句的执行次数成正比,因此通过计算执行测试来推断执行时间。算法中语句执行次数称为语句频度或时间频度,记为T(n),n是问题的规模,T是Time。
2>.什么是时间复杂度
当时间频度的n不断变化时,T(n)也在不断变化,为了考察两者变化时呈现什么规律,可以使用时间复杂度来计算。通常操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),存在一个正常数c使得f(n) * c >= T(n)恒成立。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。换句话说,只要计算一下语句的执行次数和n之间的关就可以了,去除系数部分,低阶项部分,就是时间复杂度的值了。
举个例子,在公式:“xxx = 3N^3 + 2n^2 + 5n”中,其中“2n^2”和“5n”相对于“3N^3 ”来说,属于低阶项部分,我们将其去除,在看“3N^3"中,”3“为系数部分,我们将其也去除,因此只剩下“N^3 ”啦!这个时候我们就说“xxx”的时间复杂度为“O(n^3)”。
二.时间复杂度的计算
1>.给定任意长度数组,读取数组第一个元素的值
时间复杂度为:无论数组长度n为多少,代码执行一次。因此,时间复杂度为O(1)。实现代码如下:
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.java.timeComplexity; public class Demo {
public static void main(String[] args) {
String[] names = {"尹正杰","yinzhengjie","YinZhengJie"};
String firstElement = getFirstElement(names);
System.out.println(firstElement);
} public static String getFirstElement(String[] names){
//无论数组的长度n为多少,代码只执行一次。
return names[0];
}
} /*
以上代码输出结果如下:
尹正杰
*/
2>.循环n次,输出“尹正杰(yinzhengjie)”
随着n的增大,打印函数逐渐增多。打印代码执行的次数是n,因此时间复杂度为O(n)。
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.java.timeComplexity; public class Demo {
public static void main(String[] args) {
String[] names = {"尹正杰","yinzhengjie","YinZhengJie"};
printArray(5);
} public static void printArray(int n){
for(int i = 0 ; i < n ; i ++){
//执行一次。
System.out.println("尹正杰(yinzhengjie)") ;
}
}
} /*
以上代码输出结果如下:
尹正杰(yinzhengjie)
尹正杰(yinzhengjie)
尹正杰(yinzhengjie)
尹正杰(yinzhengjie)
尹正杰(yinzhengjie)
*/
3>.打印99乘法表
打印99正方乘法表,打印语句输出9 * 9 = 81次。打印语句执行次数:n * n = n^2,因此时间复杂度是O(n^2)。
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.java.timeComplexity; public class Demo {
public static void main(String[] args) {
printArray(9);
} public static void printArray(int n){
for(int i = 1 ; i <= n ; i ++){
for(int j = 1 ; j <= i ; j ++){
//打印语句的执行次数n * n次。
System.out.printf("%d x %d = %d\t",j,i,(j*i));
}
System.out.println();
}
}
} /*
以上代码输出结果如下:
1 x 1 = 1
1 x 2 = 2 2 x 2 = 4
1 x 3 = 3 2 x 3 = 6 3 x 3 = 9
1 x 4 = 4 2 x 4 = 8 3 x 4 = 12 4 x 4 = 16
1 x 5 = 5 2 x 5 = 10 3 x 5 = 15 4 x 5 = 20 5 x 5 = 25
1 x 6 = 6 2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36
1 x 7 = 7 2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42 7 x 7 = 49
1 x 8 = 8 2 x 8 = 16 3 x 8 = 24 4 x 8 = 32 5 x 8 = 40 6 x 8 = 48 7 x 8 = 56 8 x 8 = 64
1 x 9 = 9 2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81
*/
4>.冒泡排序
冒泡排序是经典的排序算法是每次比较相邻的两个元素进行对调,进行多轮,知道数列有序。对于n个元素的冒泡排序来说,共需要比较比较次数的公式如下:
因此时间复杂度为:O(n^2),这是冒泡排序最坏的情况下的时间复杂度。具体实现代码如下:
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.java.timeComplexity; public class Demo {
public static void main(String[] args) {
char[] arr = {'i','f','c','b','d','g','e','a','h'};
printArray(arr);
bubbleSort(arr);
printArray(arr);
}
//进行冒泡排序
public static void bubbleSort(char[] arr){
//外层比较n-1次
for(int i = 0 ; i < arr.length - 1 ; i ++){
//比较n-1-i次
for(int j = 0 ; j < arr.length -1 - i ; j ++){
char temp = arr[j] ;
if(arr[j] > arr[j + 1]){
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
}
//遍历数组
public static void printArray(char[] arr){
for (int i = 0; i < arr.length; i++) {
char c = arr[i];
System.out.print(c+" ");
}
System.out.println();
} } /*
以上代码输出结果如下:
i f c b d g e a h
a b c d e f g h i
*/
冒泡排序可以进行优化,在最好的情况下,复杂度为O(n),具体代码如下:
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.java.timeComplexity; public class Demo {
public static void main(String[] args) {
char[] arr = {'i','f','c','b','d','g','e','a','h'};
printArray(arr);
bubbleSort(arr);
printArray(arr);
}
//进行冒泡排序
public static void bubbleSort(char[] arr){
//外层比较n-1次
for(int i = 0 ; i < arr.length - 1 ; i ++){
boolean flag = true ;
//比较n-1-i次
for(int j = 0 ; j < arr.length -1 - i ; j ++){
char temp = arr[j] ;
if(arr[j] > arr[j + 1]){
//发生交换,就设置标志位为false,即数列无序。
flag = false ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
//判断如果是数列有序,则终止循环。
if(flag){
break ;
}
}
}
//遍历数组
public static void printArray(char[] arr){
for (int i = 0; i < arr.length; i++) {
char c = arr[i];
System.out.print(c+" ");
}
System.out.println();
} } /*
以上代码输出结果如下:
i f c b d g e a h
a b c d e f g h i
*/
设置标志位flag=1,表示整个数列已经有序,就不需要再排序了,在里层循环中,如果发现没有进行过数据交换,就所说数列已经有序。在最好情况下,就是数列本身已经有序,只需要执行外层的n-1次循环即可,因此复杂度为O(n)。
5>.折半查找
折半查找也叫二分查找,是高效的查找方式,前提条件是数列需要时有序数列。实现代码如下:
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.java.timeComplexity; public class Demo {
public static void main(String[] args) {
char[] arr = {'a','b','c','d','e','f','g'};
int tag = 'n';
int res = halfSearch(arr, tag);
System.out.println(res);
tag = 'd';
int res2 = halfSearch(arr, tag);
System.out.println(res2); }
//进行冒泡排序
public static int halfSearch(char[] arr, int tag){
int min = arr[0] ;
int max = arr[0] ;
int mid = arr[arr.length/2] ;
for( min = 0 , max = arr.length - 1 ; min <= max ; ){
mid = (min + max) / 2 ;
//命中了
if(arr[mid] == tag){
return mid ;
}
//落在右侧范围
else if(arr[mid] < tag){
min = mid + 1 ;
}
//落在左侧范围
else{
max = mid - 1 ;
}
}
return -1;
}
} /*
以上代码输出结果如下:
-1
3
*/
折半查找的最好的时间复杂度为n(1),就是第一次折半时就恰好找到我们想要的值,当然,最坏时间复杂度为:以2为底,n的对数。即””
6>.hashmap
哈希map是java中最重要的集合之一,设计非常巧妙,使用通过数组+链表方式组合实现,哈希的目的是让对象在空间内尽可能分散。那么HashMap的时间复杂度是多少呢?
如果hashmap的每个桶内的元素个数最多不会超过一个常数C,当增加元素时,不断增加桶的数量,而保证每个桶内的元素量固定,因此就可以保证最快的查询速度,则时间复杂度就是O(C*n^2),去掉系数部分就是O(n^0) = O(1);
如果在最坏的情况下就是所有元素进入同一个桶,导致给桶内的链条非常长,则检索数据时,时间复杂度为:O(n);
7>.矩阵的乘积
矩阵我们按照阶数为n的两个方阵进行计算,矩阵的乘法运算法则为:
例如:
方阵乘法的代码如下:
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.java.timeComplexity; public class Demo {
public static void main(String[] args) {
int[][] a = {
{0,1},
{1,1}
} ;
int[][] b = {
{1,2},
{3,4}
} ; mulmatrix(a,b); }
/**
* 两个n阶方阵的乘积
* @param a
* @param b
* @return
*/
public static void mulmatrix(int[][] a , int[][] b){
int n = a.length ;
int[][] r = new int[n][n] ;
//
for(int i = 0 ; i < n ; i ++){
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
r[i][j] = r[i][j] + (a[i][k] * b[k][j] ) ;
}
}
} for(int i = 0 ; i < n ; i ++){
for (int j = 0; j < n; j++) {
System.out.print(r[i][j] + "\t");
}
System.out.println();
}
}
} /*
以上代码输出结果如下:
3 4
4 6
*/
方阵的矩阵乘法的计算次数为,因此时间复杂度为O(n^3)。
Java基础-时间复杂度计算方式的更多相关文章
- Java基础--线程创建方式
线程的创建主要有两种形式,通过继承Thread或者实现Runnable接口,本质上没有太大区别. /** * @date: 2019/7/16 **/ public class ThreadOne i ...
- Java基础 继承的方式创建多线程 / 线程模拟模拟火车站开启三个窗口售票
继承的方式创建多线程 笔记: /**继承的方式创建多线程 * 线程的创建方法: * 1.创建一个继承于Thread 的子类 * 2.重写Thread类的run()方法 ,方法内实现此子线程 要完成的功 ...
- 实用:Java基础流计算
java的流不常用,每次学习完都懂,过了一段时间就全忘了... 记录下一点实用的东西... 需求: 截取文件的前250kb内容 public static void main(String[] arg ...
- Java基础-数组常见排序方式
Java基础-数组常见排序方式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数据的排序一般都是生序排序,即元素从小到大排列.常见的有两种排序方式:选择排序和冒泡排序.选择排序的特 ...
- build path libraries java基础--Jar包添加到build path方式说明--01
摘自: http://blog.csdn.net/haolongabc/article/details/7007701 java基础--Jar包添加到build path方式说明--01 前言:这段短 ...
- 1.java小作业-计算1到100的整合-指定输入多少行输出就打印多少行-打印24小时60分钟每一分钟-重载基础练习-面向java编程初学者
可能有和我一样刚开始学习java的小伙伴们, 可以或多或少了解一点别的语言知识,我就是中途转过来的, 明白一点,关键不在语言本身····· 所以面对初学者来说,基础要学好, 下面列举几个没什么难度的小 ...
- Java基础之String中equals,声明方式,等大总结
无论你是一个编程新手还是老手,提到String你肯定感觉特别熟悉,因为String类我们在学习java基础的时候就已经学过,但是String类型有我们想象的那么简单吗?其实不然,String类型的知识 ...
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- 金三银四跳槽季,BAT美团滴滴java面试大纲(带答案版)之一:Java基础篇
Java基础篇: 题记:本系列文章,会尽量模拟面试现场对话情景, 用口语而非书面语 ,采用问答形式来展现.另外每一个问题都附上“延伸”,这部分内容是帮助小伙伴们更深的理解一些底层细节的补充,在面试中可 ...
随机推荐
- C语言学习之结构体
前言 一直以来,C语言的学习都在入门阶段,只用到数组.函数.循环.选择.位运算这些基本的知识,较少用到指针.预处理.结构体.枚举类型.文件操作等这些C语言的精髓内容,现在想想真不敢说自己熟练掌握C语言 ...
- 类调用自己的静态方法必须把该方法设置为public
否则调用不了 ParaChecker.isOK(bindingResult); public class ParaChecker { static BaseResult paraCheck(Bindi ...
- [Direct2D开发] 绘制网格
转载请注明出处:http://www.cnblogs.com/Ray1024 一.引言 最近在使用Direct2D进行绘制工作中,需要实现使用Direct2D绘制网格的功能.在网上查了很多资料,终于实 ...
- leetcode刷题笔记172 阶乘后的零
题目描述: 给定一个整数 n,返回 n! 结果尾数中零的数量. 示例1: 输入: 输出: 解释: ! = , 尾数中没有零. 示例2: 输入: 输出: 解释: ! = , 尾数中有 个零. 说明: 你 ...
- Notes of Daily Scrum Meeting(12.18)
前期落下的进度我们会在周六周日赶一下,在编译课程设计中期测试之后集中处理项目中的问题. 今天的任务总结如下: 团队成员 今日团队工作 陈少杰 调试后端连接的部分,寻找bug 王迪 测试搜索功能,修改b ...
- Linux内核分析课程期中总结
Linux内核分析课程期中总结 姓名:王朝宪 学号:20135114 注: 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com ...
- 《linux内核分析》第六周:分析fork函数对应的系统调用处理过程
一. 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235: 进程是 ...
- wordpress学习三:wordpress自带的模板学习
在<学习二>里,大概说了下怎么去查找模板,本节我们以一个简单的模板为例子,继续说说wordpress的模板机制,看看做一个自己的模板需要哪些知识点. 页面模板渲染 wordpress的模板 ...
- UIO,大页内存,CPU亲和性,NUMA机制等
Linux环境下的UIO(Userspace I/O) UIO 用户空间下驱动程序的支持机制.DPDK使用UIO机制使网卡驱动程序运行在用户态,并采用轮询和零拷贝方式从网卡收取报文,提高收发报文的性能 ...
- 调研android开发环境的发展演变
这是第一次接触android开发,特意上网搜索视频进行了自身知识补充,觉得说视频做得很不错,从android的发展历程以及一些基本常识都讲得很详细,也很有趣,也所以拿出来同大家一起分享学习,网址是:h ...