Java 二叉查找树转化为排序的循环双链表
来源:互联网 发布:时序性数据库 编辑:程序博客网 时间:2024/06/05 16:54
Java 二叉查找树转化为排序的循环双链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
例如对于下面的二分查找树:
small pointer 其实也就是指向左孩子,large pointer指向右孩子,转化为双链表之后 small pointer应该指向前一个元素,large pointer应该指向后一个元素。转化为排序的循环双链表则为:
分析
二分查找树的中序遍历即为升序排列,问题就在于如何在遍历的时候更改指针的指向。一种简单的方法时,遍历二分查找树,讲遍历的结果放在一个数组中,之后再把该数组转化为双链表。如果题目要求只能使用O(1)内存,则只能在遍历的同时构建双链表,即进行指针的替换:
我们需要用递归的方法来解决,假定每个递归调用都会返回构建好的双链表,可把问题分解为左右两个子树。
由于左右子树都已经是有序的,当前节点作为中间的一个节点,把左右子树得到的链表连接起来即可。
1 自己写的可运行的完整代码:
package cn.sjtu.practice.test3;
public class Solution33 {
/**
* 二叉树转双向链表
* @param root
* @return
*/
static TreeNode treeToList(TreeNode root) {
if (root == null) {
return null;
}
// 递归解决子树
TreeNode leftHead = treeToList(root.left);
TreeNode rightHead = treeToList(root.right);
// 把根节点转换为一个节点的双链表。方便后面的链表合并
root.left = root;
root.right = root;
if (leftHead != null) {
TreeNode leftTail = leftHead.left;
leftTail.right = root;
root.left = leftTail;
leftHead.left = root;
root.right = leftHead;
} else {
leftHead = root;
}
if (rightHead != null) {
TreeNode rightTail = rightHead.left;
root.right = rightHead;
rightHead.left = root;
// 首尾相接
leftHead.left = rightTail;
rightTail.right = leftHead;
}
return leftHead;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(5, new TreeNode(3, new TreeNode(1), new TreeNode(4)),
new TreeNode(7, null, new TreeNode(9)));
inOrderTraverse(root);
System.out.println();
TreeNode treeToList = treeToList(root);
show(treeToList);
}
public static void show(TreeNode head) {
TreeNode tempHead = head;
while (head != null) {
System.out.print(head.val + " ");
head = head.right;
if (head == tempHead) {
break;
}
}
System.out.println();
}
/**
* 中序遍历
*
* 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
*
* @param node
* 遍历的节点
*/
public static void inOrderTraverse(TreeNode node) {
if (node == null)
return;
inOrderTraverse(node.left);
System.out.print(node.val + " ");
inOrderTraverse(node.right);
}
}
2 程序2
package nowcoder.test1;
public class Convert {
public static TreeNode convert(TreeNode pRootOfTree) {
if (pRootOfTree == null) {
return null;
}
if (pRootOfTree.left == null && pRootOfTree.right == null) {
return pRootOfTree;
}
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left = convert(pRootOfTree.left);
TreeNode p = left;
// 2.定位至左子树双链表最后一个节点
while (p != null && p.right != null) {
p = p.right;
}
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if (left != null) {
p.right = pRootOfTree;
pRootOfTree.left = p;
}
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right = convert(pRootOfTree.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if (right != null) {
right.left = pRootOfTree;
pRootOfTree.right = right;
}
return left != null ? left : pRootOfTree;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(5, new TreeNode(3, new TreeNode(1), new TreeNode(4)),
new TreeNode(7, null, new TreeNode(9)));
inOrderTraverse(root);
System.out.println();
TreeNode treeToList = convert(root);
show(treeToList);
}
public static void show(TreeNode head) {
TreeNode tempHead = head;
while (head != null) {
System.out.print(head.val + " ");
head = head.right;
if (head == tempHead) {
break;
}
}
System.out.println();
}
/**
* 中序遍历
*
* 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
*
* @param node
* 遍历的节点
*/
public static void inOrderTraverse(TreeNode node) {
if (node == null)
return;
inOrderTraverse(node.left);
System.out.print(node.val + " ");
inOrderTraverse(node.right);
}
}
public class Convert {
public static TreeNode convert(TreeNode pRootOfTree) {
if (pRootOfTree == null) {
return null;
}
if (pRootOfTree.left == null && pRootOfTree.right == null) {
return pRootOfTree;
}
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left = convert(pRootOfTree.left);
TreeNode p = left;
// 2.定位至左子树双链表最后一个节点
while (p != null && p.right != null) {
p = p.right;
}
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if (left != null) {
p.right = pRootOfTree;
pRootOfTree.left = p;
}
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right = convert(pRootOfTree.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if (right != null) {
right.left = pRootOfTree;
pRootOfTree.right = right;
}
return left != null ? left : pRootOfTree;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(5, new TreeNode(3, new TreeNode(1), new TreeNode(4)),
new TreeNode(7, null, new TreeNode(9)));
inOrderTraverse(root);
System.out.println();
TreeNode treeToList = convert(root);
show(treeToList);
}
public static void show(TreeNode head) {
TreeNode tempHead = head;
while (head != null) {
System.out.print(head.val + " ");
head = head.right;
if (head == tempHead) {
break;
}
}
System.out.println();
}
/**
* 中序遍历
*
* 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
*
* @param node
* 遍历的节点
*/
public static void inOrderTraverse(TreeNode node) {
if (node == null)
return;
inOrderTraverse(node.left);
System.out.print(node.val + " ");
inOrderTraverse(node.right);
}
}
0 0
- Java 二叉查找树转化为排序的循环双链表
- 二分查找树转化为排序的循环双链表
- 二元查找树转化为排序双链表
- 二叉树转化为排序的双向链表
- 把排序数组转化为高度最小的二叉树
- 排序列表转化为二分查找树
- 二叉树------二叉查找树转化为双向链表
- 二叉树转化为双链表
- 查找二叉树转换为排序的双向链表
- 常见算法-将二叉搜索树转化为排序的双向链表(java版)
- java 将数组转化为 二叉树
- 二叉查找树转化为双向链表
- [进军硅谷]将二叉搜索树转化为一个有序的循环链表
- Java实现二叉排序(查找)树的操作
- 把排序数组转化为高度最小的搜索二叉树
- 把排序数组转化为高度最小的二叉搜索树
- 将二叉搜索树转化为一个排序的双向链表
- java排序算法_009二叉查找树
- 大整数相乘/相加
- jsp项目遇到的问题及解决方式
- caffe添加HeatmapData层 (二)
- 16. 3Sum Closest
- Windows下的服务控制管理器(SCM)
- Java 二叉查找树转化为排序的循环双链表
- nyoj248
- ZooKeeper Watch Java API浅析getData
- 求int型数据在内存中存储时1的个数
- redhat学习笔记
- Python MySQLdb 使用utf-8 编码插入中文数据
- onBackPressed:Can not perform this action after onSaveInstanceState
- c#处理json数据最好的方式
- Cocos2d-x笔记记忆整理Day5