本文目前分享的题目都是来自于July的分享,然后把具体算法实现。搜索树转双向链表主要的实现逻辑是在中序遍历时,调整节点的左右子树;因为中序遍历是递归调用,所以在调整时一定要注意调整的位置,如果写错了,很有可能造成死循环。避免的主要办法是在读完左子树时调整左节点,遍历完右子树时调整右节点,具体代码见trans函数。算法的时间复杂度是o(logn)。

输入树构建完成后是:

代码如下:

# -*- coding: utf-8 -*-
"""
题目:输入一棵二叉搜索树(记住是搜索树),将该二叉搜索树转换为一个排序的双向链表。要求:不能创建任何新的结点,只能调整树中结点指针的指向。
1 2 3 4 5 6 7 输入顺序 4 3 1 2 5 6 7用这个顺序建立二叉查找树
基本思路:用中序遍历的方式,每一个节点左侧连接的应该是左子数的最右边一个节点,而右边连接的应该是右子树最左边的节点
"""
class TreeNode:
"""
树的节点定义,后面的很多操作都是基于节点的
""" def __init__(self):
"""
定义一个树的节点,初始状态左右节点为空
"""
self.leftNode = None
self.rightNode = None def setData(self, data):
"""
设置数字的方法
args: data节点值
"""
self.data = data def setLeftNode(self, leftNode):
"""
设置左节点的方法
args: leftNode 左节点
"""
self.leftNode = leftNode def setRightNode(self, rightNode):
"""
设置右节点的方法
args: rightNode 右节点
"""
self.rightNode = rightNode def getData(self):
"""
获取节点数字
return:返回节点数字
"""
return self.data def getLeftNode(self):
"""
获取左节点
return:返回左节点
"""
return self.leftNode def getRightNode(self):
"""
获取右节点
return:返回右节点
"""
return self.rightNode class BuildTree:
"""
以输入顺序构建二叉查找树,左边的比根节点小,右侧的比根节点大
""" def build(self, dataList):
"""
开始构建树
args:dataList 树的节点值
"""
#遍历输入数组
for i in range(len(dataList)):
currData = dataList[i]
#初始化一个节点
newTreeNode = TreeNode()
newTreeNode.setData(currData);
#如果是一个输入,则作为树的根节点
if i==0:
self.tree = newTreeNode
#否则进行大小的比较,构建二叉查找树
else:
flagNode = self.tree
while flagNode is not None:
if currData <= flagNode.getData():
#如果当然值小于等于根节点,并且左节点为空的话,则进行左节点赋值
if flagNode.getLeftNode() is None:
flagNode.setLeftNode(newTreeNode)
break;
else:
#否则继续找左节点
flagNode = flagNode.getLeftNode()
else:
#如果当然值大于根节点,并且右节点为空的话,则进行右节点赋值
if flagNode.getRightNode() is None:
flagNode.setRightNode(newTreeNode)
break;
else:
#否则继续找右节点
flagNode = flagNode.getRightNode() def trans(self, tempNode):
"""
递归进行中序遍历
在左子树遍历完时,找左子树最右边的节点,做为节点的左子树
在右子树遍历完时,找左子树最右变的节点,做为节点的右子树
args:tempNode 初始为树的根节点
"""
if tempNode is not None:
#递归遍历左子树
self.trans(tempNode.getLeftNode())
#左子树遍历完成,进行左侧最右节点的查找
if tempNode.getLeftNode() is not None:
tempNode2 = tempNode.getLeftNode()
while tempNode2.getRightNode() is not None:
tempNode2 = tempNode2.getRightNode()
tempNode.setLeftNode(tempNode2)
tempNode2.setRightNode(tempNode)
#递归遍历右子树
self.trans(tempNode.getRightNode())
#右子树遍历完成,进行右侧最左节点的查找
if tempNode.getRightNode() is not None:
tempNode2 = tempNode.getRightNode()
while tempNode2.getLeftNode() is not None:
tempNode2 = tempNode2.getLeftNode()
tempNode.setRightNode(tempNode2)
tempNode2.setLeftNode(tempNode) def callTrans(self):
"""
用根节点对trans进行调用
"""
self.trans(self.tree); def test(self):
"""
进行数据的测试,分别从左到右读和从右到左读取数据
"""
tempNode = self.tree
while tempNode.getLeftNode() is not None:
#找到最左节点
tempNode = tempNode.getLeftNode()
#print tempNode.getData()
#从左向右读
while tempNode.getRightNode() is not None:
print tempNode.getData()
tempNode = tempNode.getRightNode()
print tempNode.getData()
#从右向左读
while tempNode is not None:
print tempNode.getData()
tempNode = tempNode.getLeftNode() if __name__ == "__main__":
#初始化数组
dataList = [10,6,4,8,2,5,7,9,20,15,28,14,16,24,29]
test = BuildTree()
#构建排序数
test.build(dataList)
#递归构建双向链表
test.callTrans()
#测试输出
test.test()             

输出结果:

2 4 5 6 7 8 9 10 14 15 16 20 24 28 29 29 28 24 20 16 15 14 10 9 8 7 5 4 2

欢迎关注订阅号“白话算法”

Python算法练习--把搜索树转成双向链表的更多相关文章

  1. python算法:嵌套数组转变成一维数组

    比如,输入是:[2, 1, [3, [4, 5], 6], 7, [8]] 则,输出是:[2, 1, 3, 4, 5, 6, 7, 8] def list_flatten(l, a=None): a ...

  2. [LeetCode] Convert Binary Search Tree to Sorted Doubly Linked List 将二叉搜索树转为有序双向链表

    Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right pointers ...

  3. Python算法:推导、递归和规约

    Python算法:推导.递归和规约 注:本节中我给定下面三个重要词汇的中文翻译分别是:Induction(推导).Recursion(递归)和Reduction(规约) 本节主要介绍算法设计的三个核心 ...

  4. Python算法基础

    一.简介 定义和特征 定义:算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时 ...

  5. python算法常用技巧与内置库

    python算法常用技巧与内置库 近些年随着python的越来越火,python也渐渐成为了很多程序员的喜爱.许多程序员已经开始使用python作为第一语言来刷题. 最近我在用python刷题的时候想 ...

  6. 安装Python算法库

    安装Python算法库 主要包括用NumPy和SciPy来处理数据,用Matplotlib来实现数据可视化.为了适应处理大规模数据的需求,python在此基础上开发了Scikit-Learn机器学习算 ...

  7. 剑指Offer25 二叉搜索树转换为排序双向链表

    /************************************************************************* > File Name: 25_BSTCon ...

  8. python算法(一)

    python算法(一) 一.求数x的因子 x=100 divisors=()#初始化空的元组 for i in range(1,x): if x%i==0: divisors=divisors+(i, ...

  9. Python算法与数据结构--求所有子数组的和的最大值

    Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个 ...

随机推荐

  1. Scrapy 1.4 文档 03 Scrapy 教程

    在本教程中,我们假设您已经安装了Scrapy.如果没有,请参阅安装指南. 我们将要抓取 quotes.toscrape.com,一个列出著名作家的名言(quote)的网站. 本教程将引导您完成以下任务 ...

  2. 富文本编辑器UEditor自定义工具栏(三、自定义工具栏功能按钮图标及工具栏样式简单修改)

    导读 富文本编辑器UEditor提供丰富了定制配置项,如果想设置个性化的工具栏按钮图标有无办法呢?答案是肯定的!前两篇博文简要介绍了通过将原工具栏隐藏,在自定义的外部按钮上,调用UEditor各命令实 ...

  3. jQuery学习之旅 Item3 属性操作与样式操作

    本节将Dom元素的操作:属性操作.样式操作.设置和获取HTML,文本和值.Css-Dom操作. 1.属性操作 <input type="text" name="us ...

  4. java 基础之 反射技术

    1. java代码 在 java 语言中最核心的就是代码的运行, 按照面向对象的思想,在调用java代码时往往需要先创建对象,再调用方法, 而写在方法中的即所谓的java 代码 一段java代码在程序 ...

  5. javascript快速入门之BOM模型—浏览器对象模型(Browser Object Model)

    什么是BOM? BOM是Browser Object Model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对 ...

  6. (一)JUnit简介

    单元测试是测试应用程序的功能是否能够按需要正常进行,是一个对单一实体(类或方法)的测试. JUnit是一个Java编程语言的单元测试框架. 单元测试框架是一部分代码,可以确保另一端代码(方法)按预期工 ...

  7. Semaphore简介

    Semaphore简介 Semaphore是并发包中提供的用于控制某资源同时被访问的个数 操作系统的信号量是个很重要的概念,在进程控制方面都有应用.Java 并发库 的Semaphore 可以很轻松完 ...

  8. 【欧拉函数】BZOJ2705: [SDOI2012]Longge的问题

    Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N).   Solut ...

  9. POJ_1066_Treasure Hunt_判断线段相交

    POJ_1066_Treasure Hunt_判断线段相交 Description Archeologists from the Antiquities and Curios Museum (ACM) ...

  10. 【源码安装】Heartbeat3.0.9

    1.概述1.1 关于Heartbeat1.2 本篇博客实践环境2. 部署基础环境2.1 通过YUM安装依赖环境2.2 创建Heartbeat用户和组3. 编译安装3.1下载源码包3.2 编译安装3.2 ...