java 双向链表_Day26:二叉搜索树与双向链表

53db97be6c3fc488df59a6cb6cdfc3d6.png

剑指Offer_编程题——二叉搜索树与双向链表

题目描述:

输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点。只能调整树中节点指针的指向。

具体要求:

时间限制: C/C++ 1秒,其他语言2秒
空间限制: C/C++32M,其他语言64M

具体思路:

背景知识介绍

在做该题之前,我们应该首先了解二叉搜索树,详细解释请看本文。接下来,还需要我们了解二叉树的中序遍历,因为我们做本题最关键的思想就是二叉树的中序遍历。在维基百科中,树的中序遍历为:指先访问左(右)子树,然后访问根,最后访问右(左)子树的遍历方式。例如在以下的树中:

231ab48ddc4c0a695db9cb8cff9b1959.png

其中序遍历的顺序为:A B C D E F G H I。这就是中序遍历。最后还需要掌握双链表的相关知识。在维基百科中,双向链表是这样解释的双向链表,又称为双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。以下就是一个双向链表

35286e9ecf1bc6525ebefe267974757a.png

根据题目可知:如果有以下的一颗树:

c3df22727babd2234d121a76e5c87af8.png

转换成相应的双向链表为:

efa986124a9b7af0ef6c5bef3117918b.png

具体思路:

根据我们理解的题意以及之前介绍的搜索二叉树和二叉树的中序遍历可知,二叉搜索树的中序遍历刚好是从小到大排序。因此本题的核心就是二叉搜索树的中序遍历,然后我们可以将遍历的结果存放在链表中。本题的关键是如何将左子树的最大值与右子树的最小值通过根root连接起来。比如题目中的8和12.这也是解决本题最为核心的部分。本题由于是二叉搜索树,因此有会用到我们的递归算法。其实应用递归需要我们理解递归进入的条件、递归返回的状态,如果递归进入时改变了环境,返回时应当恢复环境,就像栈的操作一样。在使用指针变量的时候一定要进行初始化,本题有一个小坑就是返回的不是表头而是root。具体我们可以用java和python来实现该思路。

1、首先用java来实现

public 

代码效果图如图所示:

5713818af749464b4194d115ede5ba13.png

正如前面提到一样,牛客网已经为我们定义了节点,不需要我们重复定义,但是在自己的本地编译器中,我们需要定义节点TreeNode的类,具体实现如下:

public 

2、接下来用python将其实现

class 

代码效果图如图所示:

8b383ba5ceca91236464d68d278cf9d9.png

用python实现树结构:

class 

总结

本道题主要二叉搜索树以及二叉树的中序遍历还有就是递归和双向链表。在解题之前我们给大家介绍了二叉搜索树、二叉树的中序遍历以及双向链表的基本知识,并且还给出了解题的思路,应用java和python两门语言将其实现,其实本题的关键就是中序遍历,还有一个小坑就是本题返回的不是链表表头,而是根节点。因此,我们需要深刻掌握树的相关实现,尤其是二叉树,并且也要掌握数据结构相关的知识,只有这样,才能遇到综合性问题做到融会贯通,写出优质的代码。总之,我们要继续加油,争取早日找到工作,Good Luck!!!

参考文献

[1]qq_23217629

[2]负雪明烛

[3]二叉搜索树

[4]二叉树的中序遍历

[5]双向链表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值