什么是算法?
广泛地说算法是解决特定问题所采取的一系列步骤。
狭义地说算法可以让我们更快更好的实现一些操作。
性能就如同经济学中的货币,而程序的可读性,交互性等等就是现实生活中的商品。
即可读性,交互等等是以牺牲性能而获得的。
大O表示法:算法的时间复杂度
注意:大O表示法说明的是最糟糕的情况下算法的运行时间
常见的算法时间复杂度:
O(1): 常数时间
O(logn):对数时间 常见算法代表:二分查找(n表示操作数)
O(n): 线性时间 常见算法代表:简单查找。
O (n * log n ) 常见算法代表:快速排序——一种速度较快的排序算法。
O(n^2) 常见算法:选择排序——一种速度较慢的排序算法。
O (n !)——一种非常慢的算法,阶乘问题
二分查找
前提:查询列表必须是有序的
C语言实现:查找分数
#include <stdio.h> int main(int argc, const char * argv[]) { //定义一个分数 for (int y=0;y<=100;y++){ int i = 0;//区间的较小值 int r = 100;//区间的较大值 int mid;//中间值 int cont=0; //猜的次数 while (r>=i) { cont++; mid=(i+r)/2; if(mid>y) r = mid-1; else if(mid<y) i = mid+1; else break;//猜中跳出循环 } printf("y:%d cont:%d",y,cont); if(y%4==0&&y!=0)printf("\n"); } return 0; }
数据结构-数组与链表
用于存储多项数据
数组:
数组中的元素在内存中的存储空间需要是连续不断的
优点:需要随机地读取元素时,数组的效率很高,因为可以迅速找到数组的任何元素。
读取数据:O(1)
插入数据:O(n)
删除数据: O(n)
链表:
链表中的元素可以存储在内存中的任何位置
链表的每个元素都存储了下一个元素的地址,从而使一系列随机的内存地址串在一起。
缺点:
在链表中,元素并非是靠在一起的,你无法迅速计算出第五个元素的内存地址,
而必须先访问第一个元素以获取第二个元素的地址,再访问第二个元素以获取第三个元素的地址,以此类推,直到访问第五个元素。
读取数据: O(n)
插入数据: O(1)
删除数据: O(1)
数组与链表对比:
插入数据 :
使用链表时,插入元素很简单,只需修改它前面的那个元素指向的地址或者插入元素指向原先第一个元素的地址。
而使用数组时,则必须将后面的元素都向后移。
如果没有足够的空间,可能还得将整个数组复制到其他地方!
删除元素:
链表也是更好的选择,因为只需修改前一个元素指向的地址即可。而使用数组时,删除元素后,必须将后面的元素都向前移。
不同于插入,删除元素总能成功。如果内存中没有足够的空间,插入操作可能失败,但在任何情况下都能够将元素删除。
数组和链表哪个用得更多呢?显然要看情况。但数组用得很多,因为它支持随机访问。有两种访问方式:随机访问 和顺序访问 。
顺序访问意味着从第一个元素开始逐个地读取元素。链表只能顺序访问:要读取链表的第十个元素,得先读取前九个元素,并沿链接找到第十个元素。
随机访问意味着可直接跳到第十个元素。我们经常说数组的读取速度更快,这是因为它们支持随机访问。很多情况都要求能够随机访问,因此数组用得很多。