【Data structure & Algorithm】把二元查找树转变成排序的双向链表
把二元查找树转变成排序的双向链表
题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,要求不能创建任何新节点,只调整指针指向。
比如将二元查找树
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表4=6=8=10=12=14=16
分析:
思路一:当到达某一节点准备调整以该节点为根节点的子树时,先调整其左子树将左子树转换成一个排好序的左子链表,再调整其右子树转换右子链表。最近链接左子链表的最右节点(左子树的最大节点)、当前节点和有子链表的最左节点(右子树的最小节点)。从树的根节点开始递归调整所有节点。
首先定义二元查找树的数据结构如下:
structBSTreeNode
{
int m_nValue;
BSTreeNode *m_pLeft;
BSTreeNode *m_pRight;
}
BSTreeNode*ConvertNode(BSTreeNode* pNode, bool asRight)
{
if (!pNode)
returnNULL;
BSTreeNode *pLeft = NULL;
BSTreeNode* pRight = NULL; //Convert the left sub-tree
if(pNode -> m_pLeft)
pLeft = ConvertNode(pNode ->m_pLeft, false); //Convert the greatest node in the leftsub-tree to the current node
if (pLeft)
{
pLeft -> m_pRight = pNode;
pNode -> m_pLeft = pLeft;
} //Convert the right sub-tree
if (pNode -> m_pRight)
pRight= ConvertNode (pNode -> m_pRight, true); //Connect the least node in the rightsub-tree to the current node
if (pRight)
{
pNode-> m_pRight = pRight;
pRight-> m_pLeft = pNode;
} BSTreeNode *pTemp = pNode; //If the current node is the right child ofits parent, return the least node in the tree whose root is the current node
if (asRight)
{
while(pTemp -> m_pLeft)
pTemp= pTemp -> m_pLeft;
}
//if the current node is the left child ofits parent, return the greatest node in the tree whose root is the current node
else
{
while(pTemp -> m_pRight)
pTemp= pTemp -> m_pRight;
}
return pTemp; //Convert a BSTree into a sorteddouble-linked list
BSTreeNode* Convert(BSTreeNode* pHeadOfTree)
{
returnConvertNode(pHeadOfTree, true);
}
思路二:中序遍历二叉树。较小节点先访问。如果访问一个节点,假设之前访问过的节点已经调整成一个排序的双向链表,再把调整当前节点的指针将其连接到链表末尾,当所有节点都访问过之后,整棵树也就转换为一个排序的双向链表了。
voidConvertNode(BSTreeNode* pNode, BSTreeNode*& pLastNodeInList)
{
if(pNode ==NULL)
return;
BSTreeNode *pCurrent = pNode; //Convert the left sub-tree
if (pCurrent -> m_pLeft !=NULL)
ConvertNode(pCurrent-> m_pLeft, pLastNodeInList); //Put the current node into thedouble-linked list
pCurrent -> m_pLeft = pLastNodeInList;
if(pLastNodeInList != NULL)
pLastNodeInList-> m_pRight = pCurrent; pLastNodeInList = pCurrent; //Convert the right sub-tree
if (pCurrent -> m_pRight != NULL)
ConvertNode(pCurrent-> m_pRight, pLastNodeInList); //Convert a BSTree into a sorteddouble-linked list
BSTreeNode* Convert_Solution(BSTreeNode*pHeadOfTree)
{
BSTreeNode*pLastNodeInList = NULL;
ConvertNode(pHeadOfTree,pLastNodeInList); //Getthe head of the double-linked list
BSTreeNode*pHeadOfList = pLastNodeInList;
while(pHeadOfList && pHeadOfList -> m_pLeft)
pHeadOfList= pHeadOfList -> m_pLeft; return pHeadOfList;
}
}
【Data structure & Algorithm】把二元查找树转变成排序的双向链表的更多相关文章
- MS - 1 - 把二元查找树转变成排序的双向链表
## 1. 把二元查找树转变成排序的双向链表 ## ### 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表. ### 要求不能创建任何新的结点,只调整指针的指向. 10 ...
- 二元查找树转变成排序的双向链表之C#算法实现
此题为July在CSDN发布的微软编程面试100题中的第一题,觉得蛮有趣的,今天也拿过来玩玩,July的代码用的是C++实现,可能因为有指针的原因吧,感觉看起来相对比较容易理解整个的实现过程,而我,试 ...
- 1.把二元查找树转变成排序的双向链表[BST2DoubleLinkedList]
[题目]:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树 . 10 / \ 6 14 / \ / \ 4 8 12 16 转 ...
- IT公司100题-15-求二元查找树的镜像
问题描述: 输入一颗二元查找树,将该树转换为它的镜像树,即对每一个节点,互换左右子树. 例如输入: 6/ \4 12/ \ / \2 5 8 16 输出: 6/ ...
- IT公司100题-9-判断整数序列是不是二元查找树的后序遍历结果
问题描述: 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果. 如果是返回true,否则返回false. 例如输入4, 8, 6, 12, 16, 14, 10,由于这一整数序列是如下树 ...
- 6.二元查找树的后序遍历结果[PostOrderOfBST]
[题目] 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: 8 ...
- 11.求二元查找树的镜像[MirrorOfBST]
[题目] 输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点.用递归和循环两种方法完成树的镜像转换. 例如输入: 8 / \ 6 1 ...
- [Data Structure & Algorithm] 七大查找算法
查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算,例如编译程序中符号表的查找.本文简单概括性的介绍了常见的七种查找算法,说是七种,其实二分查找.插值查找以及斐波那契查找 ...
- [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计
Design a data structure that supports the following two operations: void addWord(word) bool search(w ...
随机推荐
- Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例及配置文件具体解释
Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例 一.调用java程序脚本(默认已经搭建好了Java环境) 1.jdk 安装路径 /usr/jdk/jdk1.7/-- 2.j ...
- git学习(4)---工作流
一.目的 前三章介绍了git工具本身的操作,主要包含本地仓库操作和远程库操作两部分内容.接下来,我们将介绍怎样使用git进行项目开发,也叫做git工作流. git工作流分为三种模式:共享远程库模式.独 ...
- PE发送报文
步骤: 1. 在 action 中使用发送报文,要指定报文在 router 端的交易名称 2. 如果使用 supe.execute(context) 来发送,不需要第一步 3. 配置从网银到 rout ...
- PHP debug_backtrace() 函数
PHP Error 和 Logging 函数 实例 生成 PHP backtrace: <?php function a($txt) { b("Glenn"); } func ...
- maven的坑: Exception in thread "pool-1-thread-1" java.lang.NoClassDefFoundError: org/eclipse/aether/spi/connector/Transfer$State
搭建ReboletricSample的环境: 搭建完成,执行的时候报错: Exception in thread "main" java.lang.NoClassDefFoundE ...
- spring boot Mybatis多数据源配置
关于 有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据.另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据 ...
- send data to Flume client-sdk flume使用之httpSource
https://flume.apache.org/FlumeDeveloperGuide.html#client-sdk flume使用之httpSource - CSDN博客 https://blo ...
- 【Effective C++】构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函 ...
- appium(9)-uiautomator UiSelector
uiautomator UiSelector Appium enables searching using UiSelectors. UiScrollable is also supported.// ...
- 后台管理微服务(二)——docker的使用
1. docker概述 1.1 Docker是什么 Docker 是软件工业的集装箱技术 Docker 是一个容器引擎,docker提供了一套完整的容器解决方案. Docker 是一个能将开发的程序自 ...