2. 浅拷贝和深拷贝的区别?
3. 什么是哈希表?产生冲突了如何解决?
4. 什么是深度优先,什么是广度优先?
一.vector、list和map三者有何区别?
(1) vector拥有一段连续的内存空间,并且起始地址不变,对随机存取有非常好的支持,但是在中间进行插入和删除的时候需要拷贝内存空间,会影响效率.
vector适用:对象数量变化少,对象简单,随机访问元素频繁
(2) list 是数据结构中的双向链表,其空间是可以不连续的,通常通过指针来访问数据,不能对内部原始进行随机访问,占的内存会比较多.....但是由于链表的特点,则对于插入和删除操作会比较方便和高效. 对元素的拷贝时开销较大,因为拷贝时会调用拷贝构造函数.
list适用:对象数量变化大,对象复杂,插入和删除频繁
(3) map 和set 属于标准的关联容器,使用了红黑树,其插入排序比其他序列容器的效率高, 因为其不需要对内存做拷贝和移动,而是只需要替换指针就可以.
set 和map的区别是: set只含有关键字key, 而map中有一个关键字key和其对应的value,总共2个元素.
其中map 和hash_map的区别是: hash_map中使用了Hash算法来加速查找的过程,但是需要更多的内存来存放这些hash桶元素,就是利用空间来换取时间的策略.
二. 浅拷贝和深拷贝的区别?
如果B复制了A,然后修改A的时候,看B是否变化:
如果B改变了, 说明就是浅拷贝.(修改内存中的同一个值)..浅拷贝只是在内存中增加一个指针指向已经存在的内存地址,一般来说,拷贝构造函数可以完成对对象数据成员的简单复制.
如果B没有改变,说明是深拷贝.(修改堆内存中的不同值)..深拷贝增加了一个指针并且申请了新的内存,并且使这个增加的指针指向这个新的内存,然后对拷贝对象进行逐位复制,数据相对安全... 使用深拷贝时, 释放内存的时候不会因为出现浅拷贝时释放同一个内存的问题.
浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
三. 什么是哈希表?产生冲突了如何解决?
哈希表包含一个数组,通过特殊的关键字(key)来访问数组中的元素,
哈希表解决哈希冲突的方法: 开放定址法,再哈希法,链地址法
开放定址法: 当关键字key的哈希地址出现冲突时,以P为基础,产生另一个哈希地址P1,如果p1仍然冲突,则再以P为基础,再产生一个新的地址p2,....直到找到不冲突的哈希地址,然后将元素存在其中.有一个通用的再散列形式:
Hi=(H(key)+di)% m i=1,2,…,n. 其中H(key)为哈希函数,m 为表长,di称为增量序列。增量序列的取值方式不同,相应的再散列方式也不同。
再哈希法:这种方法是同时构造多个不同的哈希函数: Hi=RH1(key) i=1,2,…,k
当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。
链地址法:将产生冲突的记录存在一个链表中,哈希表中存放的是该链表的表头.(比较适合进行插入和删除)
四. 什么是深度优先,什么是广度优先?
深度优先依靠的是递归地解决问题,采用 栈的结构来解决,主要的搜索路径是从一个顶点开始,沿着一条路一直走到底,如果发现不能到达目标,就返回到上一个节点,然后从另一条路开始走到底,尽可能地往深处走.
广度优先 依赖于队列 来解决问题, 其搜索路径是从一个顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止.