我粘贴的解决方案来自 this Geek URL
用C语言编写,所以我尝试在JAVA中将其转换如下 - (如果我错了,请纠正我,我不是c/c++
人)
程序
// A simple recursive function to convert a given Binary tree to Doubly
// Linked List
// root --> Root of Binary Tree
// head --> Pointer to head node of created doubly linked list
public void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes head)
{
if(root == null)
return;
// Initialize previously visited node as NULL. This is
// declared outside the recursive function so that the same value
// is accessible in all recursive calls
prev = null;
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(root.getLeft(), head);
//set head of LL if not set
if(orgHead == null)
orgHead = root;
// Now convert this node
if (prev == null)
head = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.getRight(), head);
}
考虑中的树
10
/ \
5 15
/ \ / \
2 7 12 18
/
1
/
0
问题
该程序返回输出:
0 1 2 5 7 10 15 18
正如您所看到的,代码中缺少12
。我试图干了很多次,但仍然无法找到真正的问题.....我尝试寻找不同的解决方案,但大多数它们遍历 part-converted-LL ,这增加了时间复杂度。
答案 0 :(得分:4)
在原始C代码中,函数原型如下:
void BinaryTree2DoubleLinkedList(node *root, node **head)
**头部意味着双指针,头部值可以使用* head在函数内改变。在java中,您无法修改函数参数,因为它们始终被复制,但您可以修改数组元素。 所以请尝试以下代码:
BTNode prev;
void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes[] head)
{
// Base case
if (root == null) return;
// Initialize previously visited node as NULL. This is
// static so that the same value is accessible in all recursive
// calls
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(roor.getLeft(), head);
// Now convert this node
if (prev == null)
head[0] = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.getRight(), head);
}
初始通话应如下所示:
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
// result is in head[0]
为避免头部元素的丑陋分配,更好地制作如下的附加功能:
BTNodes BinaryTree2DoubleLinkedList(BTNodes root) {
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
return head[0];
}
答案 1 :(得分:2)
如果我们使用Node的左右字段,将二进制搜索树转换为双链接列表是一件容易的事。 递归帮助我们。
{
Node prev = null;
Node listHead = null;
Node listTail = null;
public void convertToList(Node node)
{
if(node == null)
return;
convertToList(node.left);
if(listHead == null)
listHead = node;
if(prev == null)
prev = node;
else
{
node.left = prev;
prev.right = node;
}
prev = node;
convertToList(node.right);
if(node.right == null)
listTail = node;
}
public void printList()
{
Node node = listHead;
System.out.println("Doubly Linked List from Head: ");
while(node!= null)
{
System.out.print(node.data+" ");
node = node.right;
}
}
public void printListFromTail()
{
Node node = listTail;
System.out.println("Doubly Linked List from Tail: ");
while(node!= null)
{
System.out.print(node.data+" ");
node = node.left;
}
}
}
答案 2 :(得分:0)
对于任何Google访问者,我找到了一种避免head[0]
的方法 - (如果通过不同树的不同对象调用该程序,则可能会出现问题,因为head[0]
可能会被覆盖)
以下是实施:
Trick是从代码中删除prev = null;
并在调用函数中初始化tempHead = null
和prev = null
,而不是在递归调用中。
void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes tempHead)
{
// Base case
if (root == null) return; //optional, not needed in fact
// Recursively convert left subtree
if(root.getLeft() != null) //purely to reduce number of traversed node
BinaryTree2DoubleLinkedList(root.getLeft(), tempHead);
//set Original Head of the List, this would be leftmost
//leaf in the tree
if(orgHead == null)
orgHead = root;
// Now convert this node
if (prev == null)
tempHead = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
if(root.getRight() != null) //purely to reduce number of traversed node
BinaryTree2DoubleLinkedList(root.getRight(), tempHead);
}
其他助手详情:
初次通话:
BinaryTree2DoubleLinkedList(bst.root,tempHead); //root and null value
遍历列表
printList(orgHead); //pass original head to print function
复杂性:
Time = Space : O(n)
答案 3 :(得分:0)
public void ConverttoList(Node root){
Node top = root;
top.left = GetLeftNode(top.left);
top.right = GetRightNode(top.right);
top.left.right= top;
top.right.left= top;
Node leftmost = top.left;
while(leftmost.left!=null){
leftmost = leftmost.left;
}
while(leftmost!= null) {
System.out.printf(leftmost.Data + "->");
leftmost = leftmost.right;
}
}
public Node GetLeftNode(Node root){
if(root.left == null){
return root;
}
else{
Node startnode = GetLeftNode(root.left);
startnode.right = root;
root.left = startnode;
root.right = GetRightNode(root.right);
root.right.left = root;
Node rightmost=root.right;
while (rightmost.right!=null){
rightmost=rightmost.right;
}
return rightmost;
}
}
public Node GetRightNode(Node root){
if(root.left == null){
return root;
}
else{
Node startnode = GetLeftNode(root.left);
startnode.right = root;
root.left = startnode;
root.right = GetRightNode(root.right);
root.right.left = root;
Node leftmost=root.left;
while (leftmost.left!=null){
leftmost=leftmost.left;
}
return leftmost;
}
}
答案 4 :(得分:0)
// bst to dll will generate a sorted dll
public class TreeToDLL {
public static void main(String args[]){
TreeNode t = new TreeNode(5);
TreeNode t3 = new TreeNode(3);
TreeNode t1 = new TreeNode(1);
TreeNode t7 = new TreeNode(7);
TreeNode t9 = new TreeNode(9);
TreeNode t8 = new TreeNode(8);
t.setLeft(t3);
t3.setLeft(t1);
t.setRight(t7);
t7.setRight(t9);
t9.setLeft(t8);
DllNode dll = convert(t);
dll.print();
}
static class DllNode{
int data;
DllNode next;
DllNode prev;
public DllNode(int data) {
this.data = data;
}
public DllNode() {
}
public int getData() {
return data;
}
public DllNode getPrev() {
return prev;
}
public void setPrev(DllNode prev) {
this.prev = prev;
}
public void setData(int data) {
this.data = data;
}
public DllNode getNext() {
return next;
}
public void setNext(DllNode next) {
this.next = next;
}
public void print(){
DllNode t = this;
while(t!=null){
System.out.print(t.getData()+"->");
t = t.getNext();
}
}
}
static class TreeNode{
int data;
TreeNode left;
TreeNode right;
public TreeNode(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public TreeNode getLeft() {
return left;
}
public TreeNode setLeft(TreeNode left) {
this.left = left;
return this;
}
public TreeNode getRight() {
return right;
}
public TreeNode setRight(TreeNode right) {
this.right = right;
return this;
}
}
private static DllNode convert(TreeNode t){
DllNode d =convert(t,new PreviousDLLNode());
while(d.prev!=null){
d = d.prev;
}
return d;
}
private static DllNode convert(TreeNode t, PreviousDLLNode d){
if(t==null) return null;
convert(t.getLeft(),d);
DllNode dn = new DllNode(t.getData());
if(d.val!=null){
d.val.setNext(dn);
}
dn.setPrev(d.val);
d.val = dn;
convert(t.getRight(),d);
return dn; // this node will be in the middle of the dll.
}
private static class PreviousDLLNode{
DllNode val;
}
}
答案 5 :(得分:0)
我解决了插入treenodes的问题,这些按顺序排列在这样的DLL中:
我修改了BinarySearchTree,如下所示:
select forum.title, count(comment.post_id) as count from (select * from post where parent_post_id = -1) as forum
left outer join post as topic on topic.parent_post_id = forum.post_id
left outer join post as comment on comment.parent_post_id = topic.post_id
group by forum.title
我添加了一个DoubleLinkedList字段,我在BST的默认构造函数中初始化,调用DLL的默认构造函数,我创建了下面的递归方法,灵感来自于inOrderTraversal,用于DLL中树节点的排序输入