金九银十面试题之《数据结构和算法》

这篇具有很好参考价值的文章主要介绍了金九银十面试题之《数据结构和算法》。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🐮🐮🐮
辛苦牛,掌握主流技术栈,包括前端后端,已经7年时间,曾在税务机关从事开发工作,目前在国企任职。希望通过自己的不断分享,可以帮助各位想或者已经走在这条路上的朋友一定的帮助

前言

❤️金九银十马上就要来啦,各位小伙伴们有计划跳槽的要开始准备了,博主接下来一段时间会给大家持续更新面试题目,大家持续关注一下,感谢🙏🙏🙏
之前的面试文章链接也给到大家
金九银十面试题之Mysql
金九银十面试题之设计模式

内容

📟 Q1:什么是 AVL 树?

AVL 树 是平衡二叉查找树,增加和删除节点后通过树形旋转重新达到平衡。右旋是以某个节点为中心, 将它沉入当前右子节点的位置,而让当前的左子节点作为新树的根节点,也称为顺时针旋转。同理左旋 是以某个节点为中心,将它沉入当前左子节点的位置,而让当前的右子节点作为新树的根节点,也称为 逆时针旋转。

📟 Q2:什么是红黑树?

红黑树 是 1972 年发明的,称为对称二叉 B 树,1978 年正式命名红黑树。主要特征是在每个节点上增 加一个属性表示节点颜色,可以红色或黑色。红黑树和 AVL 树 类似,都是在进行插入和删除时通过旋 转保持自身平衡,从而获得较高的查找性能。与 AVL 树 相比,红黑树不追求所有递归子树的高度差不超过 1,保证从根节点到叶尾的最⻓路径不超过最短路径的 2 倍,所以最差时间复杂度是 O(logn)。红
黑树通过重新着色和左右旋转,更加高效地完成了插入和删除之后的自平衡调整。
红黑树在本质上还是二叉查找树,它额外引入了 5 个约束条件:

  1. 节点只能是红色或黑色。
  2. 根节点 必须是黑色。
  3. 所有 NIL 节点都是黑色的。
  4. 一条路径上不能出现相邻的两个红色节点。
  5. 在任何递 归子树中,根节点到叶子节点的所有路径上包含相同数目的黑色节点。

这五个约束条件保证了红黑树的新增、删除、查找的最坏时间复杂度均为 O(logn)。如果一个树的左子节 点或右子节点不存在,则均认定为黑色。红黑树的任何旋转在 3 次之内均可完成。

📟 Q3:AVL 树和红黑树的区别?

红黑树的平衡性不如 AVL 树,它维持的只是一种大致的平衡,不严格保证左右子树的高度差不超过 1。 这导致节点数相同的情况下,红黑树的高度可能更高,也就是说平均查找次数会高于相同情况的 AVL 树。
在插入时,红黑树和 AVL 树都能在至多两次旋转内恢复平衡,在删除时由于红黑树只追求大致平衡,因 此红黑树至多三次旋转可以恢复平衡,而 AVL 树最多需要 O(logn) 次。AVL 树在插入和删除时,将向上 回溯确定是否需要旋转,这个回溯的时间成本最差为 O(logn),而红黑树每次向上回溯的步⻓为 2,回 溯成本低。因此面对频繁地插入与删除红黑树更加合适。

📟 Q4:B 树和B+ 树的区别?

B 树中每个节点同时存储 key 和 data,而 B+ 树中只有叶子节点才存储 data,非叶子节点只存储 key。 InnoDB 对 B+ 树进行了优化,在每个叶子节点上增加了一个指向相邻叶子节点的链表指针,形成了带 有顺序指针的 B+ 树,提高区间访问的性能。
B+ 树的优点在于:

  1. 由于 B+ 树在非叶子节点上不含数据信息,因此在内存⻚中能够存放更多的key, 数据存放得更加紧密,具有更好的空间利用率,访问叶子节点上关联的数据也具有更好的缓存命 中率。
  2. B+树的叶子结点都是相连的,因此对整棵树的遍历只需要一次线性遍历叶子节点即可。而 B 树则需 要进行每一层的递归遍历,相邻的元素可能在内存中不相邻,所以缓存命中性没有 B+树好。但是 B 树 也有优点,由于每个节点都包含 key 和 value,因此经常访问的元素可能离根节点更近,访问也更迅速。

📟 Q5:排序有哪些分类?

排序可以分为内部排序和外部排序,在内存中进行的称为内部排序,当数据量很大时无法全部拷⻉到内存需要使用外存,称为外部排序。
内部排序包括比较排序和非比较排序,比较排序包括插入/选择/交换/归并排序,非比较排序包括计数/ 基数/桶排序。
插入排序包括直接插入/希尔排序,选择排序包括直接选择/堆排序,交换排序包括冒泡/快速排序。

📟 Q6:直接插入排序的原理?

稳定,平均/最差时间复杂度 O(n2),元素基本有序时最好时间复杂度 O(n),空间复杂度 O(1)。
每一趟将一个待排序记录按其关键字的大小插入到已排好序的一组记录的适当位置上,直到所有待排序 记录全部插入为止。

public void insertionSort(int[] nums) {
    for (int i = 1; i < nums.length; i++){ 
    	int insertNum = nums[i];
		int insertIndex;
		for (insertIndex = i - 1; insertIndex >= 0 && nums[insertIndex] > insertNum; insertIndex--){
			nums[insertIndex + 1] = nums[insertIndex];
		}
        nums[insertIndex + 1] = insertNum;
    }
}

直接插入没有利用到要插入的序列已有序的特点,插入第 i 个元素时可以通过二分查找找到插入位置 insertIndex,再把 i~insertIndex 之间的所有元素后移一位,把第 i 个元素放在插入位置上。

public void binaryInsertionSort(int[] nums) { 
	for (int i = 1; i < nums.length; i++) {
		int insertNum = nums[i]; int insertIndex = -1; int start = 0;
		int end = i - 1;
        while (start <= end) {
            int mid = start + (end - start) / 2;
            if (insertNum > nums[mid])
                start = mid + 1;
            else if (insertNum < nums[mid])
                end = mid - 1;
            else {
                insertIndex = mid + 1;
				break; 
			}
        }
        if (insertIndex == -1)
            insertIndex = start;
        if (i - insertIndex >= 0)
		System.arraycopy(nums, insertIndex, nums, insertIndex + 1, i - insertIndex);
		nums[insertIndex] = insertNum;
} }

📟 Q7:希尔排序的原理?

又称缩小增量排序,是对直接插入排序的改进,不稳定,平均时间复杂度 O(n1.3),最差时间复杂度O(n2),最好时间复杂度 O(n),空间复杂度 O(1)。 把记录按下标的一定增量分组,对每组进行直接插入排序,每次排序后减小增量,当增量减至 1 时排序完毕。

public void shellSort(int[] nums) {
    for (int d = nums.length / 2; d > 0 ; d /= 2){ 
    	for (int i = d; i < nums.length; i++) {
			int insertNum = nums[i];
			int insertIndex;
			for (insertIndex = i - d; insertIndex >= 0 && nums[insertIndex] > 
			insertNum; insertIndex -= d) {
				nums[insertIndex + d] = nums[insertIndex];
			}
		}
	} 
}

📟 Q8:直接选择排序的原理?

不稳定,时间复杂度 O(n2),空间复杂度 O(1)。
每次在未排序序列中找到最小元素,和未排序序列的第一个元素交换位置,再在剩余未排序序列中重复 该操作直到所有元素排序完毕。

public void selectSort(int[] nums){ 
	int minIndex;
    for (int index = 0; index < nums.length - 1;index++){ 
        minIndex = index;
        for (int i = index + 1;i < nums.length;i++){ 
        	if(nums[i] < nums[minIndex])
            minIndex = i;
		}
		if (index != minIndex){ 
			swap(nums, index,minIndex); 
		}
	}
}

📟 Q9:堆排序的原理?

是对直接选择排序的改进,不稳定,时间复杂度 O(nlogn),空间复杂度 O(1)。
将待排序记录看作完全二叉树,可以建立大根堆或小根堆,大根堆中每个节点的值都不小于它的子节点 值,小根堆中每个节点的值都不大于它的子节点值。
以大根堆为例,在建堆时首先将最后一个节点作为当前节点,如果当前节点存在父节点且值大于父节 点,就将当前节点和父节点交换。在移除时首先暂存根节点的值,然后用最后一个节点代替根节点并作 为当前节点,如果当前节点存在子节点且值小于子节点,就将其与值较大的子节点进行交换,调整完堆 后返回暂存的值。

public void add(int[] nums, int i, int num){ 
	nums[i] = num;
	int curIndex = i;
	while (curIndex > 0) {
		int parentIndex = (curIndex - 1) / 2; 
		if (nums[parentIndex] < nums[curIndex])
            swap(nums, parentIndex, curIndex);
        else break;
        curIndex = parentIndex;
    }
}
public int remove(int[] nums, int size){ 
	int result = nums[0];
    nums[0] = nums[size - 1];
    int curIndex = 0;
	while (true) {
		int leftIndex = curIndex * 2 + 1;
		int rightIndex = curIndex * 2 + 2;
		if (leftIndex >= size) break;
		int maxIndex = leftIndex;
		if (rightIndex < size && nums[maxIndex] < nums[rightIndex])
            maxIndex = rightIndex;
        if (nums[curIndex] < nums[maxIndex])
            swap(nums, curIndex, maxIndex);
        else  break;
		curIndex = maxIndex; 
	}
    return result;
}

📟 Q10:冒泡排序的原理?

稳定,平均/最坏时间复杂度 O(n2),元素基本有序时最好时间复杂度 O(n),空间复杂度 O(1)。

比较相邻的元素,如果第一个比第二个大就进行交换,对每一对相邻元素做同样的工作,从开始第一对 到结尾的最后一对,每一轮排序后末尾元素都是有序的,针对 n 个元素重复以上步骤 n -1 次排序完 毕。

public void bubbleSort(int[] nums) {
    for (int i = 0; i < nums.length - 1; i++) {
		for (int index = 0; index < nums.length - 1 - i; index++) { 
			if (nums[index] > nums[index + 1])
				swap(nums, index, index + 1)
		} 
	}
}

当序列已经有序时仍会进行不必要的比较,可以设置一个标志记录是否有元素交换,如果没有直接结束 比较。

public void betterBubbleSort(int[] nums){ 
	boolean swap;
    for (int i = 0; i < nums.length - 1; i++){ 
    	swap = true;
		for (int index = 0; index < nums.length - 1 - i; index++) { 
			if (nums[index] > nums[index + 1]) {
                swap(nums, index ,index + 1);
                swap = false;
            }
		}
        if (swap) break;
    }
}

📟 Q11:快速排序的原理?

是对冒泡排序的一种改进,不稳定,平均/最好时间复杂度 O(nlogn),元素基本有序时最坏时间复杂度
O(n2),空间复杂度 O(logn)。 首先选择一个基准元素,通过一趟排序将要排序的数据分割成独立的两部分,一部分全部小于等于基准元素,一部分全部大于等于基准元素,再按此方法递归对这两部分数据进行快速排序。
快速排序的一次划分从两头交替搜索,直到 low 和 high 指针重合,一趟时间复杂度 O(n),整个算法的 时间复杂度与划分趟数有关。
最好情况是每次划分选择的中间数恰好将当前序列等分,经过 log(n) 趟划分便可得到⻓度为 1 的子表, 这样时间复杂度 O(nlogn)。
最坏情况是每次所选中间数是当前序列中的最大或最小元素,这使每次划分所得子表其中一个为空表 , 这 样⻓度为 n 的数据表需要 n 趟划分,整个排序时间复杂度 O(n2)。

public void quickSort(int[] nums, int start, int end) { 
	if (start < end) {
        int pivotIndex = getPivotIndex(nums, start, end);
        quickSort(nums, start, pivotIndex - 1);
        quickSort(nums, pivotIndex + 1, end);
	} 
}
public int getPivotIndex(int[] nums, int start, int end){ 
	int pivot = nums[start];
    int low = start;
    int high = end;
    while (low < high) {
        while (low <= high && nums[low] <= pivot)
            low++;
        while (low <= high && nums[high] > pivot)
            high--;
        if (low <  high)
		swap(nums, low, high);
    }
    swap(nums, start, high);
    return high;
}

📟 Q12:归并排序的原理?

归并排序基于归并操作,是一种稳定的排序算法,任何情况时间复杂度都为 O(nlogn),空间复杂度为O(n)。
基本原理:应用分治法将待排序序列分成两部分,然后对两部分分别递归排序,最后进行合并,使用一 个辅助空间并设定两个指针分别指向两个有序序列的起始元素,将指针对应的较小元素添加到辅助空 间,重复该步骤到某一序列到达末尾,然后将另一序列剩余元素合并到辅助空间末尾。
适用场景:数据量大且对稳定性有要求的情况。

int[] help;
public void mergeSort(int[] arr){ 
	int[] help = new
    int[arr.length]; sort(arr, 0,
    arr.length - 1);
}
public void sort(int[] arr, int start, int end){ 
	if (start == end) return;
    int mid = start + (end - start) / 2;
    sort(arr, start, mid);
    sort(arr, mid + 1, end);
	merge(arr, start, mid, end);
}
public void merge(int[] arr, int start, int mid, int end) {
	if (end + 1 - start >= 0) 
	System.arraycopy(arr, start, help, start, end + 1 - start);
    int p = start;
    int q = mid + 1;
    int index = start;
    while (p <= mid && q <= end){ 
    	if (help[p] < help[q])
            arr[index++] = help[p++];
        else
            arr[index++] = help[q++];
    }
    while (p <= mid) arr[index++] = help[p++];
    while (q <= end) arr[index++] = help[q++];
}

📟 Q13:排序算法怎么选择?

数据量规模较小,考虑直接插入或直接选择。当元素分布有序时直接插入将大大减少比较和移动记录的
次数,如果不要求稳定性,可以使用直接选择,效率略高于直接插入。 数据量规模中等,选择希尔排序。
数据量规模较大,考虑堆排序(元素分布接近正序或逆序)、快速排序(元素分布随机)和归并排序 (稳定性)。
一般不使用冒泡。

写在最后

希望博主收集的内容能帮到大家,祝大家能找到一个好的工作,过好的生活,如有错误欢迎指正。 💐💐💐文章来源地址https://www.toymoban.com/news/detail-594160.html

到了这里,关于金九银十面试题之《数据结构和算法》的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 金九银十面试题之《Spring Data JPA、Spring MVC、AOP》

    🐮🐮🐮 辛苦牛,掌握主流技术栈,包括前端后端,已经7年时间,曾在税务机关从事开发工作,目前在国企任职。希望通过自己的不断分享,可以帮助各位想或者已经走在这条路上的朋友一定的帮助 ❤️金九银十马上就要来啦,各位小伙伴们有计划跳槽的要开始准备了,博

    2024年02月15日
    浏览(31)
  • 金九银十面试怒拿6个offer——测试开发面试题整理

    金九银十面试怒拿6个offer——测试开发面试题整理 1、软件测试的流程是什么? 2、测试用例主要有哪些元素? 3、软件测试有什么策略和阶段? 4、黑盒测试和白盒测试是什么?二者有什么区别? 5、软件测试有什么类型? 6、测试用例是什么?有什么作用? 7、你平时是怎么

    2023年04月08日
    浏览(22)
  • Java面试1000题突击班(抓住金九银十) 持续更新中(二)

    **Java面试1000题突击班(抓住金九银十) 持续更新中(一)** 1.Spring原理、特点等 原理:它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。但是Spring可以和其他框架无缝整合。 特点:轻量级、控制反转、面向、切面、容器(可以看我的SpringIO

    2024年02月08日
    浏览(35)
  • 2023金九银十Java面试八股文大全1200道面试题附答案详解,最全面详细

    我的回答是: 很有必要 。你可以讨厌这种模式,但你一定要去背,因为不背你就进不了大厂。现如今,Java 面试的本质就是八股文,把八股文面试题背好,面试才有可能表现好。金九银十招聘黄金季已经来临!大家在考研和找工作中纠结的时候,不妨先看一下面试题,毕竟我

    2024年02月13日
    浏览(33)
  • 疫情下,我的金九银十计划

    2到3年是一个阶段,想要加薪,还得跳槽.我也不例外. 往年的3-4月、9-10月,招聘市场都有很多岗位可选,但今年真的是少得可怜.大家也感觉到了吧.还有份工作,活着好像真的也很不错了.不过该准备的还是准备,没准就有了呢. 以往的备战,我都打开百度,java面试攻略,找一大堆内容,没想

    2024年02月17日
    浏览(31)
  • 软件测试金九银十即将到来,求职套路多你有多大把握拿offer

    面试问题第一问,95%都会是:请简单的做个自我介绍吧~分以下几点说明。 1、年纪太大与太小,都不需要主动去说明。 比如我年纪只有20岁 例子:面试官您好,我叫***,来自于哪里,从事软件测试工作有几年了。 2、专业不对口也不要过多的去提及(提到了就会增加问你的概

    2024年02月10日
    浏览(24)
  • maven项目打包跳过单元测试,又是一年金九银十

    org.apache.maven.plugins maven-surefire-plugin 2.22.2 true 方法二(建议) 通过idea 工具实现,点击右上角 有点像闪电样子的图标,看到 test 被划掉了。然后点击maven 打包的功能就可以跳过测试了。 Maven命令栏的工具栏有下图中的图标,这个图标就是 Skip Tests。点击选中,再用LifeStyle中的

    2024年04月11日
    浏览(23)
  • 数据结构与算法面试

    1、链表反转 需要三个指针,一个pre指针指向反转的前一个节点,cur指向要反转的节点,然后设置有一个temp指针指向需要反转的下一个节点,用来使得cur指针移动,因为我们反转之后,无法使用next指针访问到后一个节点 2、数组实现队列 1、入队 2、出队 1、冒泡排序 比较相邻

    2024年02月09日
    浏览(28)
  • 【数据结构面试常见问题】

    数据结构作为计算机的一门基础学科,它在面试中占有很大的比重,本科阶段,我们也学过数据结构与算法,内容比较多,也比较难,尤其是图的应用以及各类查找和排序算法,这些也都是核心内容。数据结构在实际的应用中也比较多,因此,整理一些常见的笔试、面试的数

    2024年03月22日
    浏览(34)
  • 【数据结构】二叉树面试题

    目录 1.二叉树的最大深度 2.相同的树 3.另一棵树的子树 4.翻转二叉树 5.平衡二叉树 6.对称二叉树 7.完全二叉树 8.二叉树遍历 9.层序遍历 10.根据中序和前序序列构造二叉树 11.根据中序和后序序列构造二叉树 12.二叉树的最近公共祖先 13.非递归前序遍历 14.非递归中序遍历 15.非递

    2024年02月11日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包