链表与树是面试中出现频率最高的数据结构。

链表

之所以频率比较高,是因为在面试那中时长控制下,时间上是不允许面试官有太多的时间考察算法题,所以一些高难度的算法题一般都是说出一些思路或者写出核心算法就好,而难度太低的数组和字符串考察难度太低而被很多面试官选择性的放弃,再说链表这种数据结构,结构简单,但是可以考察的点会很多,简单点的像写出链表的插入和删除方法,难点的直接一道相关算法题,但是整体的代码量都不是很大,难度也不会很简单。整体来说之所以面试考察的比较频繁,就是因为代码量少而精,有一定难度从而有了一定的筛选度,作为动态数据结构能考察面试者的代码功底,所以被选择作为面试中算法考察必备题目之一。

链表的考法有很多,作者在书中举了很多的例子,比如链表逆置,删除一个节点,删除倒数第k个节点,反转链表,合并两个排序的链表,两个链表的第一个公共节点,环形链表,双向链表,复杂链表等

这里作者给出了一个比较简单的例子,可以感受下链表做题感觉。

面试题6:从尾到头打印链表_文选的blog-CSDN博客

二叉树:

二叉树的数据结构长的样子大家都明白,面试的话基础就是先中后序的遍历方法,二叉树为什么大家都喜欢考,原因可能是代码短小适合在面试短时间内考察,而且考这一个就顺手考察了链表,或者为了考而考,算法题中很多,但是实际上项目代码中使用的并不太多(红黑树那个梗)。

首先是二叉树的结点,就是上面双向链表的节点:

class ListNode(object):def __init__(self, x=None, left=None, right=None):self.left = leftself.val = xself.right = right

因为本身二叉树就是一种递归的数据结构,创建和读取都可以用递归的方式完成

二叉树的特点就是

1.除了根节点,所有的节点都有父节点;

2.除了叶子节点,所有的节点都有子节点;

3.二叉树中,第 i 层最多有 2的i次方-1 个结点;

4.如果二叉树的深度为 K,那么此二叉树最多有 2的K次方-1 个结点;

5.

6.

简单了解下就好,下面重点就是这先中后序遍历的递归和非递归写法

先序遍历:

就是先访问节点,再访问左子节点,最后访问右子节点

比如这个

这个二叉树的遍历结果就是:

先序遍历:A-B-D-G-C-E-F

中序遍历:D-G-B-A-E-C-F

后序遍历:G-D-B-E-F-C-A

一个小问题:代码中如何创建一颗二叉树,二叉树的创建方法有很多,二叉树如果比较简单的话,通过手工创建即可,数量比较大或者在编程中遇到,还是需要去创建的,这里先简单提一种创建二叉树的方法

首先的问题是,根据一个先序遍历的结果是无法找到一个准确的二叉树的,所以这里需要把结果补充完整,比如这里的先序遍历结果是A-B-D-G-C-E-F,将叶子节点的左右空节点用#来表示,树中空出的节点也用#表示,就可以将对应的二叉树转换成一种扩展的二叉树,这里的话对应的扩展二叉树的先序遍历结果就是A-B-D-#-G-#-#-#-C-E-#-#-F-#-#

当然这种算法本身也是一种递归算法,所以就要找出它的对应的递归实现条件:

1. 递归的出口:结果中没有值了

2. 递归每次实现的功能是什么:创建一个根节点和两个子节点

3. 递归返回值:返回本层中创建好的root节点

所以二叉树的先序递归创建代码就是这样的:

class ListNode(object):def __init__(self, x=None, left=None, right=None):self.left = leftself.val = xself.right = rightdef newBinaryTree(root,nums):if len(nums) == 0:returnif nums[0] != "#":root = ListNode(nums.pop(0))root.left = newBinaryTree(root.left,nums)root.right = newBinaryTree(root.right,nums)return rootelse:root = Nonenums.pop(0)return rootnums = list("ABD#G###CE##F##")
root = newBinaryTree(None,nums)

创建好之后,我们可以用先中后序的方法依次遍历下这个创建好的二叉树,验证下上述代码创建的二叉树正确性

三种递归遍历

def preOrder(root): #先序遍历if root == None:returnprint (root.val)preOrder(root.left)preOrder(root.right)def inOrder(root): # 中序遍历if root == None:returninOrder(root.left)print (root.val)inOrder(root.right)def postOrder(root): # 后序遍历if root == None:returninOrder(root.left)inOrder(root.right)print (root.val)

三种非递归遍历

def preOrderNorecur(root): # 先序遍历非递归if root == None:returnstack = [root]while stack:s = stack.pop()if s:print(s.val)stack.append(s.right)stack.append(s.left)def inOrderNorecur(root): # 中序遍历非递归if root == None:returnstack = []while stack or root:while root:stack.append(root)root = root.leftroot = stack.pop()print(root.val)root = root.rightdef postOrderNorecur(root): # 后序遍历非递归if root == None:returnstack = []while stack or root:while root:                 # 下行循环,直到找到第一个叶子节点stack.append(root)if root.left:           # 能左就左,不能左就右root = root.left else:root = root.right     s = stack.pop()print(s.val)#如果当前节点是上一节点的左子节点,则遍历右子节点if stack and s == stack[-1].left: root = stack[-1].rightelse:root = None

还有一种层次遍历,一般面试不会问,可以了解一下,就是从上到下从左到右输出当前的二叉树,上图所示的二叉树的层次遍历结果就是:A-B-C-D-E-F-G

代码实现就是:

def BFS(root):queue = [root]while queue:n = len(queue)for i in range(n):q = queue.pop(0)if q:print(q.val)queue.append(q.left if q.left else None)queue.append(q.right if q.right else None)

除了最上面说的通过扩展的方法来重建二叉树,也可以通过先序和中序遍历重建二叉树,比如会由这样的面试题,(对应的说lc的 重建二叉树 )

根据给出的先序和中序遍历结果,重建二叉树(已知没有重复元素):

先序遍历 1,2,4,7,3,5,6,8

中序遍历 4,7,2,1,5,3,8,6

看到这种面试题,首先要知道二叉树的性质,比如二叉树的先序遍历结果中,第一个肯定是root,而中序遍历的结果,根节点在中间,也就是说 4 7 2为左子树,5 3 8 6为右子树

所以程序的第一步就是找到左子树,右子树以及根节点

# -*- coding:utf-8 -*-
class ListNode(object):def __init__(self, x=None, left=None, right=None):self.left = leftself.val = xself.right = rightdef rebuildBinaryTree(list_preorder,list_inorder):root = list_preorder[0]root_index = list_inorder.index(root)list_leftbinary = list_inorder[:root_index]list_rightbinary = list_inorder[root_index:]list_preorder = [1,2,4,7,3,5,6,8]
list_rightbinary = [4,7,2,1,5,3,8,6]
rebuildBinaryTree(list_preorder,list_inorder)

实际上现在关于左子树和右子树,又可以分别看成两个二叉树,因为本身二叉树就是递归的,所以从这里可以看出来,这道题实际上还是递归的解法比较简单

# -*- coding:utf-8 -*-
class TreeNode(object):def __init__(self, x=None, left=None, right=None):self.left = leftself.val = xself.right = rightdef myBuildTree(preorder_left, preorder_right, inorder_left, inorder_right):if preorder_left > preorder_right:return None# 前序遍历中的第一个节点就是根节点preorder_root = preorder_left# 在中序遍历中定位根节点inorder_root = index[preorder[preorder_root]]# 先把根节点建立出来root = TreeNode(preorder[preorder_root])# 得到左子树中的节点数目size_left_subtree = inorder_root - inorder_left# 递归地构造左子树,并连接到根节点# 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素root.left = myBuildTree(preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1)# 递归地构造右子树,并连接到根节点# 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素root.right = myBuildTree(preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right)return root
preorder = [1,2,4,7,3,5,6,8]
inorder = [4,7,2,1,5,3,8,6]
n = len(preorder)
# 构造哈希映射,帮助我们快速定位根节点
index = {element: i for i, element in enumerate(inorder)}
myBuildTree(0, n - 1, 0, n - 1)

不解释了,背过吧。。。真心不知道面试官自己有没有写过几个二叉树的。。。。

作者在这里,提了两道比较基础的题

链表与树 python相关推荐

  1. python链表和树实验报告_关于Python实现树结构和链表结构的一点想法

    关于Python实现树结构和链表结构的一点想法 Python由于内置的数据结构具有很高的灵活性,所以可以用很多种方式来构建树.图.链表等结构 1. 树的Python实现 python自然可以使用cla ...

  2. python中递归函数基例_智慧树python答案

    智慧树python答案 s = "abcd1234",find()函数可以在字符串中搜索子串,s.find("cd")返回的结果是__________. 单tr ...

  3. id3决策树 鸢尾花 python_机器学习之分类回归树(python实现CART)

    机器学习之分类回归树(python实现CART) 之前有文章介绍过决策树(ID3).简单回顾一下:ID3每次选取最佳特征来分割数据,这个最佳特征的判断原则是通过信息增益来实现的.按照某种特征切分数据后 ...

  4. python程序设计的选择题_智慧树Python程序设计基础选择题答案

    智慧树Python程序设计基础选择题答案 更多相关问题 [单选,A2型题] 男性,36岁.摔伤头部,左颞部着力,昏迷,左瞳孔散大.X线摄片示左颞骨折线跨过脑膜中动脉.最可能的诊断是() [单选,A1型 ...

  5. python逐笔输入数据_知到智慧树Python数据分析与数据可视化结课测验

    知到智慧树Python数据分析与数据可视化结课测验答案 更多相关问题 已知三角形三个顶点的坐标是A(-1,2,3),B(1,1,1),C(0,0,5),试证三角形ABC是直角三角形,并求角B-- Wh ...

  6. 新农慕课python答案第八周_2021年智慧树Python语言应用第五单元章节测试答案选修课网课慕课答案...

    2021年智慧树Python语言应用第五单元章节测试答案选修课网课慕课答案 更多相关问题 前摄抑制和倒摄抑制现象可以作为证据支持某种遗忘理论,这一遗忘理论是A.衰退说B.干扰说C.压抑说D 2013年 ...

  7. python安装扩展库常用_树Python安装扩展库常用的是()工具

    树Python安装扩展库常用的是()工具 创业的要素主要包括:①创业者②资金③项目④场地A:错B:对 边缘检测最通用的方法是检测亮度值的不连续性,这样的不连续是用一阶和二阶导数检测的.A:对B:错 由 ...

  8. 洛谷——P1047 校门外的树 python实现

    洛谷--P1047 校门外的树 python实现 l, m = map(int, input().split(' ')) trees = [True]*(l+1) for i in range(m): ...

  9. 机器学习-决策树之回归树python实战(预测泰坦尼克号幸存情况)(三)

    本文用通俗易懂的方式来讲解分类树中的回归树,并以"一维回归的图像绘制"和"泰坦尼克号幸存者预测"两个例子来说明该算法原理. 以下是本文大纲: 1 Decisio ...

最新文章

  1. 第十四篇:有概率的上下文无关语法Probabilistic Context-Free Grammar
  2. 您有一份意外的福利待领取!
  3. Arrays.sort 不区分大小写 排序
  4. OpenCV计算图像的平均值和标准差的函数meanStdDev函数的使用
  5. linux可平通网关但不能上网,redhat问题:能ping通网关和本网段的IP,但是不能ping通DNS,也不能上网...
  6. java properties文件 安全_java 数据库读取工具类(读取config.properties配置文件)[包含线程安全] | 学步园...
  7. 动态生成的DOM不会触发onclick事件的原因及解决方法
  8. 使用help()输入keywords查看python中定义的关键字
  9. android java 图形_java – 在Android中呈现的图像上的锯齿状边缘
  10. java 百度地图返回坐标_Java使用百度地图API,根据地址,查询地址坐标。
  11. android布局性能,Android开发——布局性能优化的一些技巧(一)
  12. matlab麦克斯韦电磁方程组,从麦克斯韦方程组到电磁波动方程
  13. 51单片机与HC-05蓝牙模块(手机蓝牙控制小灯之小白速成)
  14. python k线形态识别_K线形态及识别要点大全
  15. SaaSBase:什么是Teambition?
  16. 【SpringBoot】11、SpringBoot中使用Lombok
  17. C# System.Net.Mail 类 使用465端口邮件不成功
  18. 搜索引擎技术 ——链接分析
  19. 如何用ps做故障艺术风格效果
  20. 使用C语言计算1+2+3+...+100

热门文章

  1. npm adduser报500
  2. laravel接口 接口文档
  3. windows7与linux共存,windows7和linux可以并存吗?
  4. 数据结构队列的创建,入队,出队
  5. 市政绿化工厂园林建筑设计园林景观类企业公司通用官网/产品案例展示/SEO友好/免费授权
  6. Z-score标准化的python代码
  7. Java Mail 附件名太长导致接收端附件名解析出错
  8. Android图形系统系统篇之HWC
  9. 超好用!免费使用的Sketch在线版真香!
  10. n模块切换node版本