[程序员面试题精选100题]1.把二叉查找树转变成排序的双向链表

本文主要是介绍[程序员面试题精选100题]1.把二叉查找树转变成排序的双向链表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【题目】

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

比如将二叉查找树
                                            10
                                          /    \
                                        6       14
                                      /  \     /  \
                                         4     8  12    16
转换成双向链表4=6=8=10=12=14=16


参考:程序员面试题精选100题(01)-把二元查找树转变成排序的双向链表

【思路】

本题是微软的面试题。很多与树相关的题目都是用递归的思路来解决,本题也不例外。

我们可以中序遍历整棵树。按照这个方式遍历树,比较小的结点先访问。如果我们每访问一个结点,假设之前访问过的结点已经调整成一个排序双向链表,

我们再把调整当前结点的指针将其链接到链表的末尾。当所有结点都访问过之后,整棵树也就转换成一个排序双向链表了。

【代码】

/*********************************
*   日期:2013-12-17
*   作者:SJF0115
*   题目: 把二元查找树转变成排序的双向链表
*   来源:微软
*   分类:经典面试题
**********************************/
#include <iostream>
using namespace std;struct TreeNode{int val;TreeNode *left;TreeNode *right;TreeNode(int x):val(x),left(NULL),right(NULL){}
};
//中序遍历过程中改变
// 转换后pre指向双向链表的最后一个节点
// root成为中间节点
void ConvertDoubleList(TreeNode* root, TreeNode*& pre) {if(root == NULL){return;}// 当前节点TreeNode* cur = root;// 左子节点if(cur->left){ConvertDoubleList(cur->left,pre);}// 中间节点 改成双向链表cur->left = pre;if(pre != NULL){pre->right = cur;}//if// 前一节点pre = cur;// 右子节点if(cur->right){ConvertDoubleList(cur->right,pre);}//if
}
// 二叉查找树插入
void TreeInsert(TreeNode*& root,int val){// 创建新节点TreeNode* node = new TreeNode(val);if(root == NULL){root = node;}else{TreeNode *pre = NULL;TreeNode *cur = root;// 寻找插入位置while(cur){// 父节点pre = cur;// 沿左子树方向下降if(val < cur->val){cur = cur->left;}// 沿右子树方向下降else{cur = cur->right;}}//while// 插入左子结点处if(val < pre->val){pre->left = node;}// 插入右子结点处else{pre->right = node;}//if}//if
}// 中序遍历
void InOrder(TreeNode* root){if(root == NULL){return;}if(root->left){InOrder(root->left);}cout<<root->val<<endl;if(root->right){InOrder(root->right);}
}
//输出双向链表
void PrintDoubleList(TreeNode *head){TreeNode *cur = head;if(cur == NULL){return;}// 反向遍历while(cur->left){cout<<cur->val<<"->";cur = cur->left;}cout<<cur->val<<"->NULL"<<endl;// 正向遍历while(cur){cout<<cur->val<<"->";cur = cur->right;}cout<<"NULL"<<endl;
}int main(){int array[] = {10,6,14,4,8,12,16};// 创建二叉查找树TreeNode *root = NULL;for(int i = 0;i < 7;i++){TreeInsert(root,array[i]);}// 中序遍历// InOrder(root);// 二叉查找树转换为双向链表TreeNode *pre = NULL;ConvertDoubleList(root,pre);// 打印双向链表PrintDoubleList(pre);return 0;
}







这篇关于[程序员面试题精选100题]1.把二叉查找树转变成排序的双向链表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/723261

相关文章

Python中lambda排序的六种方法

《Python中lambda排序的六种方法》本文主要介绍了Python中使用lambda函数进行排序的六种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1.对单个变量进行排序2. 对多个变量进行排序3. 降序排列4. 单独降序1.对单个变量进行排序

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

深入手撕链表

链表 分类概念单链表增尾插头插插入 删尾删头删删除 查完整实现带头不带头 双向链表初始化增尾插头插插入 删查完整代码 数组 分类 #mermaid-svg-qKD178fTiiaYeKjl {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

建立升序链表

题目1181:遍历链表 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2744 解决:1186 题目描述: 建立一个升序链表并遍历输出。 输入: 输入的每个案例中第一行包括1个整数:n(1<=n<=1000),接下来的一行包括n个整数。 输出: 可能有多组测试数据,对于每组数据, 将n个整数建立升序链表,之后遍历链表并输出。 样例输