问题:在不创建任何新的节点的情况下,实现将一颗BST变成有序的双向链表。  

分析:

  在结构上,如图的一颗BST,每个节点都有left right指针分别指指向左右儿子。结构上和双向链表节点是完全相同的。  

  在有序上,BST中序遍历的结果刚好是我们想要的双向链表的顺序,那么对于一个节点来说,他的left一定指向双向链表当前

最后一个节点。这样完全可以通过保存当前结果的最后一个节点,来实现双向链表的串联。

  具体的,我们可以先找到整棵树的最靠左的节点,作为双向链表的起始点,同时也是初始状态的last_node节点。不断处理lastnode与current node之间的关系并更新last node 即可。

//
// main.cpp
// BSTToList
//
// Created by LiJinxu on 2017/2/26.
// Copyright © 2017年 LiJinxu. All rights reserved.
// #include <iostream>
#include <cstdio>
#include <string> using namespace std; typedef struct TNode {
TNode *left, *right;
int val;
TNode(int v):val(v){}
}*pNode; pNode rt; void createBST(pNode p)
{
string num;
while (cin>>num) {
p = rt;
if(num != "#"){
pNode newNode = new TNode(atoi(num.c_str()));
if(p == NULL){
rt = newNode;
}else{
int n = atoi(num.c_str());
while (p){
if(n > p -> val){
if(p -> right == NULL){
p -> right = newNode;
break;
}
else
p = p -> right;
}else{
if(p -> left == NULL){
p -> left = newNode;
break;
}
else
p = p -> left;
}
}
}
}else{
break;
}
}
} void travelBST(pNode p)
{
if(p){
travelBST(p -> left);
cout<<"node: "<<p->val<<endl;
travelBST(p -> right);
}
} pNode lastNode;
pNode lBeginNode; pNode findTheLeftNode(pNode p)
{
if(p){
if(p -> left == NULL) return p;
else return findTheLeftNode(p -> left);
}
return NULL;
} void convert(pNode p)
{
if (p) {
convert(p -> left);
if(lastNode != p){
p -> left = lastNode;
lastNode -> right = p;
lastNode = p;
}else{
p -> left = NULL;
}
convert(p -> right); }
} void dispDLink(pNode p){
p = lBeginNode;
pNode lEndNode = NULL;
cout<<"From left to right: "<<endl;
while (p) {
cout<<p->val<<" ";
if(p -> right == NULL) lEndNode = p;
p = p -> right;
}
cout<<endl<<"end node: "<<lEndNode->val<<endl;
p = lEndNode;
cout<<"From right to left: "<<endl;
while (p) {
cout<<p->val<<" ";
p = p -> left;
}
} void solve(pNode rt)
{
lBeginNode = findTheLeftNode(rt);
lastNode = lBeginNode;
convert(rt);
cout<<"begin node: "<<lBeginNode->val<<endl;
dispDLink(lBeginNode);
} int main(int argc, const char * argv[]) {
createBST(rt);
//travelBST(rt);
solve(rt);
return ;
}

  

BST二叉查找树转双向链表DoubleLinke的更多相关文章

  1. 数据结构学习-BST二叉查找树 : 插入、删除、中序遍历、前序遍历、后序遍历、广度遍历、绘图

    二叉查找树(Binary Search Tree) 是一种树形的存储数据的结构 如图所示,它具有的特点是: 1.具有一个根节点 2.每个节点可能有0.1.2个分支 3.对于某个节点,他的左分支小于自身 ...

  2. 【算法Everyday】第一日 二叉查找树转双向链表

    算法题目链接:http://bbs.csdn.net/topics/350093707 题目 // 1.把二元查找树转变成排序的双向链表 // 题目: // 输入一棵二元查找树,将该二元查找树转换成一 ...

  3. C++数据结构之二叉查找树(BST)

    C++数据结构之二叉查找树(BST) 二分查找法在算法家族大类中属于“分治法”,二分查找的过程比较简单,代码见我的另一篇日志,戳这里!因二分查找所涉及的有序表是一个向量,若有插入和删除结点的操作,则维 ...

  4. [学习笔记] 二叉查找树/BST

    平衡树前传之BST 二叉查找树(\(BST\)),是一个类似于堆的数据结构, 并且,它也是平衡树的基础. 因此,让我们来了解一下二叉查找树吧. (其实本篇是作为放在平衡树前的前置知识的,但为了避免重复 ...

  5. BST树

    http://www.cnblogs.com/bizhu/archive/2012/08/19/2646328.html 4. 二叉查找树(BST) Technorati 标记: 二叉查找树,BST, ...

  6. 纯数据结构Java实现(4/11)(BST)

    个人感觉,BST(二叉查找树)应该是众多常见树的爸爸,而不是弟弟,尽管相比较而言,它比较简单. 二叉树基础 理论定义,代码定义,满,完全等定义 不同于线性结构,树结构用于存储的话,通常操作效率更高.就 ...

  7. JS高级-数据结构的封装

    最近在看了<数据结构与算法JavaScript描述>这本书,对大学里学的数据结构做了一次复习(其实差不多忘干净了,哈哈).如果能将这些知识捡起来,融入到实际工作当中,估计编码水平将是一次质 ...

  8. 游戏引擎架构 (Jason Gregory 著)

    第一部分 基础 第1章 导论 (已看) 第2章 专业工具 (已看) 第3章 游戏软件工程基础 (已看) 第4章 游戏所需的三维数学 (已看) 第二部分 低阶引擎系统 第5章 游戏支持系统 (已看) 第 ...

  9. Convert Sorted Array to Binary Search Tree

    Convert Sorted Array to Binary Search Tree Given an array where elements are sorted in ascending ord ...

随机推荐

  1. litepal创建数据库表失败

    今天学习郭神的litepal框架遇到了一个坑,就是程序正常跑了,但是数据库和表完全没创建!!!!!!! 先核对了litepal.xml文件,确认配置正确,assets文件夹放的也正确,最后发现竟然是因 ...

  2. SecurityContextHolder.getContext().getAuthentication()为null的情况

    原理: UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication() . ...

  3. 剑指Offer - 开始没做出来 —— 验证后序序列是否正确

    https://www.nowcoder.net/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176&tPage= ...

  4. linux c 获取当前执行进程总数

    获取当前执行进程总数的命令为: ps auxw | wc -l 获取当前执行进程总数的源代码例如以下: #include <stdio.h> #include <stdlib.h&g ...

  5. Linux 内核开发 - 内存管理

    1.1什么是内存管理 内存管理是对计算机内存进行分配和使用的技术.内存管理主要存在于多任务的操作系统中,因为内存资源极其有限.须要在不同的任务之间共享内存,内存管理的存在就是要高效.高速的非配内存,并 ...

  6. rsync 3.1.1源代码编译安装配置

    http://rsync.samba.org/ rsync-3.1.1.tar.gz ---0.卸载rpm # yum remove rsync -----1.安装: tar -zxvf rsync- ...

  7. linux设备驱动归纳总结(八):2.match.probe.remove

    linux设备驱动归纳总结(八):2.总线.设备和驱动的关系 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  8. Maven手工安装jar包到本地仓库

    使用maven,少不了的就是要被"包下载失败"这种问题折腾. jar包下载失败后.我们选择手工把jar下载下来.(能够下载到指定jar的途经非常多) 以下随便找了一个jar包为例. ...

  9. Android如何进行单元测试

    Menifest.xml中加入: <application>中加入: <uses-library android:name="android.test.runner&quo ...

  10. http trigger 事件源是事件的生产者,函数是事件的处理者

    以函数计算作为 API 网关后端服务_用户指南(开放 API)_API 网关-阿里云  https://help.aliyun.com/document_detail/54788.html 创建触发器 ...