Python算法练习--把搜索树转成双向链表
本文目前分享的题目都是来自于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算法练习--把搜索树转成双向链表的更多相关文章
- python算法:嵌套数组转变成一维数组
比如,输入是:[2, 1, [3, [4, 5], 6], 7, [8]] 则,输出是:[2, 1, 3, 4, 5, 6, 7, 8] def list_flatten(l, a=None): a ...
- [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 ...
- Python算法:推导、递归和规约
Python算法:推导.递归和规约 注:本节中我给定下面三个重要词汇的中文翻译分别是:Induction(推导).Recursion(递归)和Reduction(规约) 本节主要介绍算法设计的三个核心 ...
- Python算法基础
一.简介 定义和特征 定义:算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时 ...
- python算法常用技巧与内置库
python算法常用技巧与内置库 近些年随着python的越来越火,python也渐渐成为了很多程序员的喜爱.许多程序员已经开始使用python作为第一语言来刷题. 最近我在用python刷题的时候想 ...
- 安装Python算法库
安装Python算法库 主要包括用NumPy和SciPy来处理数据,用Matplotlib来实现数据可视化.为了适应处理大规模数据的需求,python在此基础上开发了Scikit-Learn机器学习算 ...
- 剑指Offer25 二叉搜索树转换为排序双向链表
/************************************************************************* > File Name: 25_BSTCon ...
- python算法(一)
python算法(一) 一.求数x的因子 x=100 divisors=()#初始化空的元组 for i in range(1,x): if x%i==0: divisors=divisors+(i, ...
- Python算法与数据结构--求所有子数组的和的最大值
Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个 ...
随机推荐
- Scrapy 1.4 文档 03 Scrapy 教程
在本教程中,我们假设您已经安装了Scrapy.如果没有,请参阅安装指南. 我们将要抓取 quotes.toscrape.com,一个列出著名作家的名言(quote)的网站. 本教程将引导您完成以下任务 ...
- 富文本编辑器UEditor自定义工具栏(三、自定义工具栏功能按钮图标及工具栏样式简单修改)
导读 富文本编辑器UEditor提供丰富了定制配置项,如果想设置个性化的工具栏按钮图标有无办法呢?答案是肯定的!前两篇博文简要介绍了通过将原工具栏隐藏,在自定义的外部按钮上,调用UEditor各命令实 ...
- jQuery学习之旅 Item3 属性操作与样式操作
本节将Dom元素的操作:属性操作.样式操作.设置和获取HTML,文本和值.Css-Dom操作. 1.属性操作 <input type="text" name="us ...
- java 基础之 反射技术
1. java代码 在 java 语言中最核心的就是代码的运行, 按照面向对象的思想,在调用java代码时往往需要先创建对象,再调用方法, 而写在方法中的即所谓的java 代码 一段java代码在程序 ...
- javascript快速入门之BOM模型—浏览器对象模型(Browser Object Model)
什么是BOM? BOM是Browser Object Model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对 ...
- (一)JUnit简介
单元测试是测试应用程序的功能是否能够按需要正常进行,是一个对单一实体(类或方法)的测试. JUnit是一个Java编程语言的单元测试框架. 单元测试框架是一部分代码,可以确保另一端代码(方法)按预期工 ...
- Semaphore简介
Semaphore简介 Semaphore是并发包中提供的用于控制某资源同时被访问的个数 操作系统的信号量是个很重要的概念,在进程控制方面都有应用.Java 并发库 的Semaphore 可以很轻松完 ...
- 【欧拉函数】BZOJ2705: [SDOI2012]Longge的问题
Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). Solut ...
- POJ_1066_Treasure Hunt_判断线段相交
POJ_1066_Treasure Hunt_判断线段相交 Description Archeologists from the Antiquities and Curios Museum (ACM) ...
- 【源码安装】Heartbeat3.0.9
1.概述1.1 关于Heartbeat1.2 本篇博客实践环境2. 部署基础环境2.1 通过YUM安装依赖环境2.2 创建Heartbeat用户和组3. 编译安装3.1下载源码包3.2 编译安装3.2 ...