数据结构与算法学习笔记01(引言)
引言:
看到网上一段话是这样写的:
“算法是程序的灵魂,为什么有些网站能够在高并发和海量吞吐情况下依然坚如磐石,大家可能会说: 网站使用了服务器集群技术、数据库读写分离和缓存技术(比如memcahced和redis等),那如果我再深入的问一句,这些优化技术又是怎样被那些天才的技术高手设计出来的呢? 我在上大学的时候就在想,究竟是什么让不同的人写出的代码从功能看是一样的,但从运行效率上却有天壤之别,就拿以前在软件公司工作的实际经历来说吧,我是做服务器的,环境是UNIX系统,功能是要支持上千万人同时在线,并保证数据传输的稳定,,在服务器上线前,做过内测,一切OK,可实际上线后,服务器就支撑不住了,公司的CTO(首任sina技术总监)花了3天时间对我的代码进行优化,再次上线,坚如磐石。那一瞬间,我认识到程序是有灵魂的,就是算法。如果你不想永远都是一个代码工人,不想当孬种程序员,那就花点时间来研究一下算法吧!而算法的基石是—数据结构。”
感悟颇深,于是决定克服自己浮躁的心态,静下心来,认真学习一下数据结构与算法,为以后在软件编程这一条路上打上一个好的基础。
思维导图:
算法效率的度量:
注意:
1、判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,更应该关注主项(最高项)的阶数。
2、判断一个算法好不好,我们只能通过少量的数据是不能做准确判断的,很容易以偏概全。
1、算法的时间复杂度
平方阶:
int i,j,n= 100;
for (i= 0;i <n;i++)
{
for(j =i;j<n;j++)
{
printf("this is a demo!");
}
}
总的执行次数为:
n+(n-1)+(n-2)+……+1=n(n+1)/2=n2 /2+n/2
时间复杂度为o(n2)。
对数阶:
int i= 1, n = 100;
while (i<n)
{
i=i * 2;
}
循环次数:x=log(2)n
常用的时间复杂度所耗费的时间从小到大依次是:
O(1) < O(logn) < (n) < O(nlogn) < O(n^2) < O(n^3) <O(2^n) < O(n!) < O(n^n)
2、算法的空间复杂度
完全可以用空间换取时间。
举个例子说,要判断某年是不是闰年,你可能会花一点心思来写一个算法,每给一个年份,就可以通过这个算法计算得到是否闰年的结果。
另外一种方法是,事先建立一个有2050个元素的数组,然后把所有的年份按下标的数字对应,如果是闰年,则此数组元素的值是1,如果不是元素的值则为0。
这样,所谓的判断某一年是否为闰年就变成了查找这个数组某一个元素的值的问题。
第一种方法相比起第二种来说很明显非常节省空间,但每一次查询都需要经过一系列的计算才能知道是否为闰年。
第二种方法虽然需要在内存里存储2050个元素的数组,但是每次查询只需要一次索引判断即可。