1.描写算法时间复杂度的大O几号含义是什么?
算法的时间复杂度,即算法的时间量度T(n),一般来说,依赖于问题的规模n。通常算法中基本操作被重复执行的次数是问题规模n的某个函数f(n),算法的时间复杂度主要分析T(n)的数量级,而算法中基本运算的频度f(n)和T(n)是同数量级的,算法的时间量度记作:T(n)=O(f(n)),其中’O’的含义是T(n)的数量级。
按数量级递增排列,常见的时间复杂度有:常数阶O(1),对数阶O(log2(n)),线性阶O(n),线性对数阶O(nlog2(n)),平方阶O(n2),立方阶O(n3),K次方阶O(nk),指数阶O(2n)。
随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
2.顺序表与链表分别有什么优缺点?基于空间与时间等因素,他们有哪些区别?
顺序表和和链表都是存储结构
顺序表的特点是表中元素的逻辑顺序和物理顺序相同,因而具有随机访问的特性,其优点是可以随机访问表中任一元素,随机存取任一元素,因而也铸成了它的缺点,在插入或删除的时候,需要移动大量的元素,需要预先分配足够大的空间;
链表是通过指针来表示元素间的逻辑关系,它的优点是解决了顺序表需要大量连续存储空间的缺点,动态存储分配不会造成溢出,操作灵活,但它的缺点正是,需要比顺序表多出一倍的存储空间来存放指针域,存储密度不够大,同时并不支持随机访问。
3.单链表的各种操作的算法思想分别是什么?如何判断一个单链表中是否有环?
插入操作:假设在单链表中的两个数据元素a,b之间插入一个元素x,首先要生成一个数据域为x的结点,令其指针域为指向结点b,左后要修改结点a的指针域指向该新结点x,从而形成新的结点逻辑关系。一般在单链表的第i个位置插入元素,首先要找到其前驱结点即第i-1个结点,然后按上面算法修改元素之间逻辑关系即可。
删除操作:单链表中删除元素只要将欲删除结点的前驱结点的指针域修改为该结点的后继结点,再将其删除即可。
逆置操作:用指针p开始指向第一个结点,先将头结点L的next域设置为NULL形成新的空链表,然后用*p扫描原单链表,从第一个结点开始,依次前插到新表中头结点后面,直到最后一个结点为止,该算法的辅助空间为O(1)。
判断链表是否有环:定义两个指针p、q,同时指向头结点,p移动一步,q移动两步,经过n次后,如果p、q指向同一个结点,则说明有环。
4.链表头插法与尾插法的执行过程分别是什么?如何将元素递增有序的两个带头结点的单链表归并成一个元素非递减有序的单链表?
头插法:将新节点插到链表表头,即头结点之后
尾插法:将新节点插入到链表表尾上,增加一个尾指针,尾指针指向每次插入后的结点。
Merge:假设两个有序单链表A,B递增有序,设置两个指针p,q分别用来遍历这两个链表,同时遍历A,B并比较这两个结点,如果*p<=*q,则将链表A中的结点插入到C中,同时指针向后移动,否则,将B中q指向的结点插入到C中,指针q向后移动,重复上面的操作,直到这两个链表全部遍历完为止。