您的位置:首页 > 职场人生

《剑指offer》(面试题27):二叉搜索树与双向链表

2018-02-02 18:37 281 查看
中序遍历算法的特点是按照从小到大的顺序遍历二叉树的每一个结点。

前言

在计算机领域有一类算法叫分治法,即“分而治之”。采用的就是各个击破的思想,我们把分解后的小问题各个解决,然后把小问题的解决方案结合起来解决大问题。

题目描述

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

解题思路

哇偶,中序遍历啊!中序遍历,递归和循环都可以撒~

二叉搜索树是一种排序的数据结构,每个结点都有两个指向子结点的指针。在双向链表中,每个结点也有两个指针,他们分别指向前一个结点和后一个结点。在二叉搜索树中,左子结点的值总是小于父结点的值,右子结点的值总是大于父结点的值。因此我们在转换成排序双向链表时,原先指向左子结点的指针调整为链表中指向前一结点的指针,原先指向右子结点的指针调整为链表中指向后一个结点指针。

中序遍历在二叉搜索树中的特点是按照从小到大的顺序遍历二叉树的每一个结点。下图中,我们可以把树分成三个部分:值为10的结点、根结点为6的左子树、根结点为14的右子树。根绝排序链表的定义,值为10的结点将和它的左子树的最大一个结点链接起来,同时它还将和右子树最小的结点链接起来。



按照中序遍历的顺序,当我们遍历转换到根结点时,它的左子树已经转换成一个排序的链表了,并且处在链表中最后一个的结点是当前值最大的结点。我们把值为8的结点和根结点链接起来,10就成了最后一个借点,接着我们就去遍历转换右子树,并把根结点和右子树中最小的结点链接起来。

下面个分别用C/C++和Python来实现,其中递归1是书中的解法,递归2是更加容易理解的解法,原理都是一样的,只不过递归1中涉及到指针的指针,容易把自己搞蒙。

Python版代码实现

递归

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
def Convert(self, pRootOfTree):
# write code here
if not pRootOfTree:
return None
if not pRootOfTree.left and not pRootOfTree.right:
return pRootOfTree
#遍历左子树
pLeft = self.Convert(pRootOfTree.left)
pCurrent = pLeft
#定位至左子树最右的一个结点
while pCurrent and pCurrent.right:
pCurrent = pCurrent.right
#如果左子树不为空,则将当前pRootOfTree加到左子树链表
if pLeft:
pCurrent.right = pRootOfTree
pRootOfTree.left = pCurrent
#遍历右子树
pRight = self.Convert(pRootOfTree.right)
#如果右子树不为空,则将当前pRootOfTree加到右子树链表
if pRight:
pRight.left = pRootOfTree
pRootOfTree.right = pRight

return pLeft if pLeft else pRootOfTree


循环

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
def Convert(self, pRootOfTree):
# write code here
s = []
pCurrent = pRootOfTree
pHeadOfList = None
pLastNodeInList = None
while pCurrent or s:
while pCurrent:
s.append(pCurrent)
pCurrent = pCurrent.left
if s:
pCurrent = s.pop()
if pLastNodeInList:
pLastNodeInList.right = pCurrent
pCurrent.left = pLastNodeInList
else:
pHeadOfList = pCurrent
pLastNodeInList = pCurrent
pCurrent = pCurrent.right
return pHeadOfList
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: