转自【五月的仓颉】 http://www.cnblogs.com/xrq730/p/5122436.htmlhtml
数据结构算法
数据结构是计算机存储、组织数据的方式,是指数据相互之间存在一种或多种特定关系的数据元素的集合。一般状况下,精心选择的数据结构能够带来更高的运行或者存储效率(这就是为何咱们要研究数据结构的缘由),数据结构每每同高效的检索算法和索引技术相关。数组
常见的数据结构有数组、栈、队列、链表、树、散列等,这些数据结构将是本数据结构的分类中重点研究的对象。数据结构
算法分析异步
算法是为求解一个问题须要遵循的、被清楚指定的简单指令的集合。对于一个问题,一旦某种算法给定而且(以某种方式)被肯定是正确的,那么重要的异步就是肯定该算法将须要多少注入时间或空间等资源量的问题。若是:数据结构和算法
一、一个问题的求解算法居然须要长达一年时间,那么这种算法就很难有什么用处函数
二、一个问题须要若干个GB的内存的算法,在当前大多数机器上也是没法使用的测试
数学基础spa
不管是数据结构仍是算法分析,都用到了大量的数学基础,下面将这些数学的基础简单总结一下:code
一、指数
(1)XAXB = XA+B
(2)XA/XB = XA-B
(3)(XA)B = XABsi
(4)XN + XN = 2XN ≠ X2N
(5)2N + 2N = 2N + 1
二、对数
(1)XA = B当且仅当logxB = A
(2)logAB = logCB / logCA
(3)logAB = logA + logB,A>0且B>0
三、级数
(1)∑2i = 2N+1 - 1
(2)∑Ai = (AN+1 - 1) / (A - 1),若0<A<1,则有∑Ai ≤ 1 / (1 - A)
四、模运算
若是N整除A、N整除B,那么就说A与B模N同余,记为A≡B(mod N)。直观地看,这意味着不管是A仍是B被N去除,所得余数都是相同的,因而假若有A≡B(mod N),则:
(1)A + C ≡ B + C(mod N)
(2)AD ≡ BD (mod N)
时间复杂度
在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。这是一个关于表明算法输入值的字符串的长度的函数,时间复杂度经常使用大O符号表述,不包括这个函数的低阶项和首项系数,使用这种方式时,时间复杂度可被称为是渐进的,他考察当输入值大小趋近无穷时的状况。
那么首先先看一个简单的例子,这里是计算Σi3的一个简单程序片断:
1 public static void main(String[] args) 2 { 3 System.out.println(sum(5)); 4 } 5 6 public static int sum(int n) 7 { 8 int partialSum; 9 10 partialSum = 0; 11 for (int i = 0; i <= n; i++) 12 partialSum += i * i * i; 13 14 return partialSum; 15 }
对这个程序片断的分析是简单的:
一、声明不记入时间
二、第10行和都14行各占一个时间单元
三、第12行每次执行占用4个时间单元(两次乘法、一次加法和一次赋值),而执行N次共占用4N个时间单元
四、第11行在初始化i,测试i≤n和对i的自增都隐含着开销,全部这些总开销是初始化1个时间单元,全部的测试为N+1个时间单元,全部自增为N个时间单元,共2N+2个时间单元
忽略调用方法和返回值的开销,获得总量是6N+4个时间单元,按照最开始的定义不包括这个函数的低阶项和首项系数,所以咱们说该方法的时间复杂度是O(N)。继而,咱们顺便得出若干个通常法则:
法则一----for循环
一个for循环的运行时间至可能是该for循环内部那些语句(包括测试)的运行时间乘以迭代的次数,所以假如一个for循环迭代N次,那么其时间复杂度应该为O(N)
法则二----嵌套for循环
从里向外分析这些循环,在一组嵌套循环内部的一条语句总的运行时间为该语句的运行时间乘以该组全部的for循环的大小的乘积,所以假若有如下代码:
1 public static int mutliSum(int n) 2 { 3 int k = 0; 4 for (int i = 0; i < n; i++) 5 { 6 for (int j = 0; j < n; j++) 7 { 8 k++; 9 } 10 } 11 12 return k; 13 }
则其时间复杂度应为O(N2)
法则三----顺序语句
将各个语句的运行时间求和便可,好比有如下代码:
1 public static int sum(int n) 2 { 3 int k = 0; 4 5 for (int i = 0; i < n; i++) 6 k++; 7 for (int i = 0; i < n; i++) 8 { 9 for (int j = 0; j < n; j++) 10 { 11 k++; 12 } 13 } 14 15 return k; 16 }
第一个for循环的时间复杂度为N,第二个嵌套for循环的时间复杂度为N2,综合起来看sum方法的时间复杂度为O(N2)
常见的时间复杂度与时间效率的关系有以下的经验规则:
O(1) < O(log2N) < O(n) < O(N * log2N) < O(N2) < O(N3) < 2n < 3n < n!
至于每种时间复杂度对应哪一种数据结构和算法,后面都会讲到,从上面的经验规则来看:前四个算法效率比较高,中间两个差强人意,后三个比较差(只要n比较大,这个算法就动不了了)。