数据结构常见问题系列(一)

  • Post author:
  • Post category:其他




1. 数组和链表的区别

1). 从逻辑结构来看,数组必须固定长度,数据不能动态增减,即数组的大小一旦定义就不能改变。当数据增加时,可能超过原先定义的元素的个数;当数据减少时,造成内存的浪费;链表动态进行存储分配,可以适应数据动态地增减的情况,且方便地插入、输出数据项。

2). 从内存存储的角度看,数组从栈中分配空间,对程序员方便快速,但是自由度小;链表从堆中分配空间,自由度大但是申请管理比较麻烦。

3). 从访问方式看,数组在内存中是连续的存储,因此可以利用下标索引进行访问;链表是链式存储结构,在访问元素的时候只能通过线性方式由前到后顺序访问,访问效果比较低。


关键词:长度、存储、访问




2. 简述快速排序

1). 选择一个基准元素,通常选择第一个元素或者最后一个元素。

2). 通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的元素值比基准值大。

3). 此时基准元素在其排好序后的正确位置。

4). 然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。




3. 排序算法对比


时间复杂度

1). 平方阶



(

O

(

n

2

)

)

(O(n^{2} ))






(


O


(



n











2










)


)





排序:直接插入、直接选择和冒泡排序;

2). 线性对数阶



(

O

(

n

l

o

g

2

n

)

)

(O(nlog2n))






(


O


(


n


l


o


g


2


n


)


)





排序:快速排序、堆排序、归并排序;

3). 线性阶



(

O

(

n

)

)

(O(n))






(


O


(


n


)


)





排序:基数排序,此外还有桶、箱排序;

说明:

当原表有序或基本有序时,直接插入排序和冒泡排序将大大减少比较次数和移动记录的次数,时间复杂度可降至



O

(

n

)

O(n)






O


(


n


)





而快速排序则相反,当原表基本有序时,将蜕化为冒泡排序,时间复杂度提高为



(

O

(

n

2

)

)

(O(n^{2} ))






(


O


(



n











2










)


)





原表是否有序,对简单选择排序、堆排序、归并排序和基数排序的时间复杂度影响不大。




4. 稳定性

若待排序的序列中,存在多个具有相同关键字的记录,经过排序,这些记录的相对次序保持不变,则称该算法是稳定的;若经排序后,记录的相对次序发生了改变,则称该算法是不稳定的。

稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序

不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序




5. 用循环比递归效率高吗?

递归和循环两者完全可以互换。不能完全决定性地说循环地效率比递归的效率高。


1). 递归算法:


优点:

代码简洁、清晰,并且容易验证正确性。


缺点:

它的运行需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理(还有可能出现堆栈溢出的情况),比如参数传递需要压栈等操作,会对执行效率有一定影响。但是,对于某些问题,如果不使用递归,那将是极端难看的代码。在编译器优化后,对于多次调用的函数处理会有非常好的效率优化,效率未必低于循环。


2). 循环算法:


优点:

速度快,结构简单。


缺点:

并不能解决所有的问题,有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。



6. 解决哈希冲突的方法

哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。

线性探测法、平方探测法、 伪随机序列法、拉链法




7. KMP算法

在一个字符串中查找是否包含目标的匹配字符串。




8. B树

根据B类树的特点,构造一个多阶的B类树,然后在尽量多的在结点上存储相关的信息,保证层数尽量的少,以便后面我们可以更快的找到信息,磁盘的I/O操作也少一些,而且B类树是平衡树,每个结点到叶子结点的高度都是相同,这也保证了每个查询是稳定的。

B树和B+树的区别,以一个m阶树为例。


1). 关键字的数量不同:

B+树中分支结点有m个关键字,其叶子结点也有m个,其关键字只是起到了一个索引的作用,但是B树虽然也有m个子结点,但是其只拥有m-1个关键字。


2). 存储的位置不同:

B+树中的数据都存储在叶子结点上,也就是其所有叶子结点的数据组合起来就是完整的数据,但是B树的数据存储在每一个结点中,并不仅仅存储在叶子结点上。


3). 分支结点的构造不同:

B+树的分支结点仅仅存储着关键字信息和儿子的指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息。


4). 查询不同:

B树在找到具体的数值以后,则结束,而B+树则需要通过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程中走了一条从根结点到叶子结点的路径。



版权声明:本文为weixin_43283397原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。