Java 将二叉搜索树转换为双链接列表-不工作
我粘贴的解决方案来自 它是用C写的,所以我试着用JAVA将其转换为如下内容-(如果我错了,请纠正我,我不是Java 将二叉搜索树转换为双链接列表-不工作,java,algorithm,linked-list,binary-search-tree,Java,Algorithm,Linked List,Binary Search Tree,我粘贴的解决方案来自 它是用C写的,所以我试着用JAVA将其转换为如下内容-(如果我错了,请纠正我,我不是C/C++person) 节目 // 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
C/C++
person)
节目
// 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
在代码中缺失。我多次尝试对其进行干运行,但仍然无法找到真正的问题…..我尝试搜索不同的解决方案,但大多数都在转换的LL部分中遍历,这增加了时间复杂度。在原始C代码中,函数原型如下所示:
void BinaryTree2DoubleLinkedList(node *root, node **head)
BTNodes BinaryTree2DoubleLinkedList(BTNodes root) {
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
return head[0];
}
**head表示双指针,可以使用*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]
为了更好地避免头元素的难看分配,请执行以下附加功能:
void BinaryTree2DoubleLinkedList(node *root, node **head)
BTNodes BinaryTree2DoubleLinkedList(BTNodes root) {
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
return head[0];
}
在原始C代码中,函数原型如下:
void BinaryTree2DoubleLinkedList(node *root, node **head)
BTNodes BinaryTree2DoubleLinkedList(BTNodes root) {
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
return head[0];
}
**head表示双指针,可以使用*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]
为了更好地避免头元素的难看分配,请执行以下附加功能:
void BinaryTree2DoubleLinkedList(node *root, node **head)
BTNodes BinaryTree2DoubleLinkedList(BTNodes root) {
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
return head[0];
}
对于任何谷歌访问者,我都想出了一种避免
head[0]
-(如果通过不同树的不同对象调用程序,这可能会带来问题,因为head[0]
可能会被覆盖)
以下是实施方案:
诀窍是删除prev=null从代码中选择code>并在调用函数中初始化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
Time = Space : O(n)
遍历列表
printList(orgHead); //pass original head to print function
复杂性:
BinaryTree2DoubleLinkedList(bst.root,tempHead); //root and null value
Time = Space : O(n)
对于任何谷歌访问者,我都想出了一种避免head[0]
-(如果通过不同树的不同对象调用程序,这可能会带来问题,因为head[0]
可能会被覆盖)
以下是实施方案:
诀窍是删除prev=null从代码中选择code>并在调用函数中初始化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
Time = Space : O(n)
遍历列表
printList(orgHead); //pass original head to print function
复杂性:
BinaryTree2DoubleLinkedList(bst.root,tempHead); //root and null value
Time = Space : O(n)
若我们使用节点的左字段和右字段,那个么将二叉搜索树转换为双链表是一项很容易的任务。
递归在这里帮助我们
- 首先,一直走到左边的节点。将最左边的叶节点指定为prev,同时也指定为列表头李>
- 一旦控件从叶节点返回到其父节点,则将当前节点(即左节点的父节点)指定为上一个节点的右侧,将当前节点的左侧指定为叶节点。
当前节点的右叶子节点也是如此
- 一旦我们脱离了完全递归,我们将有一个双链表,带有listHead和listTail
{
}如果我们使用节点的左字段和右字段,则将二叉搜索树转换为双链表是一项简单的任务。
递归在这里帮助我们
- 首先,一直走到左边的节点。将最左边的叶节点指定为prev,同时也指定为列表头李>
- 一旦控件从叶节点返回到其父节点,则将当前节点(即左节点的父节点)指定为上一个节点的右侧,将当前节点的左侧指定为叶节点。
当前节点的右叶子节点也是如此
- 一旦我们脱离了完全递归,我们将有一个双链表,带有listHead和listTail
{
}我解决了在DLL中按顺序插入树节点的问题,如下所示:
我在我的netBeans包中添加了所需的DoubleLinkedList和BinarySearchTree类(包括TreeNode和DoubleNode等),并且
我修改了BinarySearchTree,如下所示:
public class BinarySearchTree {
DoubleLinkedList dL;
TreeNode root;
public BinarySearchTree() {
this.root = null;
this.dL=new DoubleLinkedList();
}
public void
tree2DList(TreeNode TN) {
if (TN == null) {
return ;
} else {
tree2DList(TN.left);
dL.insertLast((YourClassOfObjects)TN.getItem());
tree2DList(TN.right);
}
return;
}
我添加了一个DoubleLinkedList字段,我在BST的默认构造函数中初始化了该字段,调用了DLL的默认构造函数,并创建了下面的递归方法,其灵感来自并遵循inOrderTraversal,用于DLL中树节点的排序输入。我解决了在DLL中按顺序插入树节点的问题,如下所示:
我在我的netBeans包中添加了所需的DoubleLinkedList和BinarySearchTree类(包括TreeNode和DoubleNode等),并且
我修改了BinarySearchTree,如下所示:
public class BinarySearchTree {
DoubleLinkedList dL;
TreeNode root;
public BinarySearchTree() {
this.root = null;
this.dL=new DoubleLinkedList();
}
public void
tree2DList(TreeNode TN) {
if (TN == null) {
return ;
} else {
tree2DList(TN.left);
dL.insertLast((YourClassOfObjects)TN.getItem());
tree2DList(TN.right);
}
return;
}
我添加了一个DoubleLinkedList字段,我在BST的默认构造函数中初始化了该字段,调用了DLL的默认构造函数,并创建了下面的递归方法,其灵感来自并遵循inOrderTraversal,用于DLL中树节点的排序输入,请在这里为你的手势留言:)什么意思?留言?@KickButtowski:人们在往下看,但不要提及原因!:)我支持你,伙计。我也有同样的问题,但你的问题让我很感兴趣;)附言:如果你打算否决投票,请在这里为你的手势写下评论:)你什么意思?KickButtowski:people downvoye,但不要提及原因!:)我支持你,伙计。我也有同样的问题,但你的问题让我很感兴趣;)BTNodes[]head
的初始调用应该是什么?我在原始函数中找不到此代码:if(orgHead==null)orgHead=root;从原始函数更新我的转换代码。请尝试一下,这是为了标记原始头部……在我们拥有头部[0]
逻辑之前……现在正在工作……谢谢,伙计,你让我开心了!:)很好的片段。但我认为代码没有把head和l连接起来