Java 使一棵树与另一棵树相等的BST旋转
我有一个问题: 您将获得两个非空的二叉搜索树T1和T2。T1和T2存储相同的键。然而,这两棵树的结构是不同的。实现一个算法,使用T1上的旋转使其等效于T2。也就是说,两棵树应该具有相同的结构。请注意,您只允许使用旋转,并且只允许在T1上使用;不允许以任何其他方式修改树 如果有人能帮助我朝着正确的方向实施这项计划,我将非常感激。这是到目前为止的代码Java 使一棵树与另一棵树相等的BST旋转,java,rotation,binary-search-tree,nodes,search-tree,Java,Rotation,Binary Search Tree,Nodes,Search Tree,我有一个问题: 您将获得两个非空的二叉搜索树T1和T2。T1和T2存储相同的键。然而,这两棵树的结构是不同的。实现一个算法,使用T1上的旋转使其等效于T2。也就是说,两棵树应该具有相同的结构。请注意,您只允许使用旋转,并且只允许在T1上使用;不允许以任何其他方式修改树 如果有人能帮助我朝着正确的方向实施这项计划,我将非常感激。这是到目前为止的代码 import java.io.*; import java.util.*; public class BST { /** *
import java.io.*;
import java.util.*;
public class BST
{
/**
* Problem: Perform rotations on tree1 to make it equivalent to tree2.
*/
public static void problem(BST tree1, BST tree2)
{
// Implement me!
//Base Case
if(tree1 == null && tree2 == null){
return;
}
}
// ---------------------------------------------------------------------
// Do not change any of the code below!
private class Node
{
public Node left = null;
public Node right = null;
public Node parent = null;
public int key;
public Node(int key)
{
this.key = key;
}
}
private Node root = null;
public int getRootKey()
{
return root.key;
}
private Node find(int key)
{
for (Node cur = root; cur != null;)
{
if (key < cur.key)
{
cur = cur.left;
}
else if (key == cur.key)
{
return cur;
}
else // key > cur.key
{
cur = cur.right;
}
}
return null;
}
// x y
// / \ / \
// a y => x c
// / \ / \
// b c a b
private void rotateL(Node xNode)
{
Node xPar = xNode.parent;
boolean isRoot = xPar == null;
boolean isLChild = !isRoot && xPar.left == xNode;
Node yNode = xNode.right;
Node beta = yNode.left;
if (isRoot) root = yNode;
else if (isLChild) xPar.left = yNode;
else xPar.right = yNode;
yNode.parent = xPar;
yNode.left = xNode;
xNode.parent = yNode;
xNode.right = beta;
if (beta != null) beta.parent = xNode;
}
// y x
// / \ / \
// x c => a y
// / \ / \
// a b b c
private void rotateR(Node yNode)
{
Node yPar = yNode.parent;
boolean isRoot = yPar == null;
boolean isLChild = !isRoot && yPar.left == yNode;
Node xNode = yNode.left;
Node beta = xNode.right;
if (isRoot) root = xNode;
else if (isLChild) yPar.left = xNode;
else yPar.right = xNode;
xNode.parent = yPar;
xNode.right = yNode;
yNode.parent = xNode;
yNode.left = beta;
if (beta != null) beta.parent = yNode;
}
public void insert(int key)
{
if (root == null)
{
root = new Node(key);
return;
}
Node par = null;
for (Node node = root; node != null;)
{
par = node;
if (key < node.key)
{
node = node.left;
}
else if (key > node.key)
{
node = node.right;
}
else // key == node.key
{
// Nothing to do, because no value to update.
return;
}
}
// Create node and set pointers.
Node newNode = new Node(key);
newNode.parent = par;
if (key < par.key) par.left = newNode;
else par.right = newNode;
}
public int[] getInOrder()
{
if (root == null) return new int[] { };
Stack<Node> stack = new Stack<Node>();
ArrayList<Integer> orderList = new ArrayList<Integer>();
for (Node node = root;;)
{
if (node == null)
{
if (stack.empty()) break;
node = stack.pop();
orderList.add(node.key);
node = node.right;
}
else
{
stack.push(node);
node = node.left;
}
}
int[] order = new int[orderList.size()];
for (int i = 0; i < order.length; i++)
{
order[i] = orderList.get(i);
}
return order;
}
public int[] getPreOrder()
{
if (root == null) return new int[] { };
Stack<Node> stack = new Stack<Node>();
ArrayList<Integer> orderList = new ArrayList<Integer>();
for (Node node = root;;)
{
if (node == null)
{
if (stack.empty()) break;
node = stack.pop();
node = node.right;
}
else
{
orderList.add(node.key);
stack.push(node);
node = node.left;
}
}
int[] order = new int[orderList.size()];
for (int i = 0; i < order.length; i++)
{
order[i] = orderList.get(i);
}
return order;
}
}
导入java.io.*;
导入java.util.*;
公共类BST
{
/**
*问题:在树1上执行旋转,使其与树2等效。
*/
公共静态无效问题(BST树1、BST树2)
{
//实施我!
//基本情况
if(tree1==null&&tree2==null){
返回;
}
}
// ---------------------------------------------------------------------
//不要更改下面的任何代码!
私有类节点
{
公共节点left=null;
公共节点权限=null;
公共节点父节点=null;
公钥;
公共节点(int键)
{
this.key=key;
}
}
私有节点根=null;
public int getRootKey()
{
返回root.key;
}
专用节点查找(int键)
{
对于(节点cur=root;cur!=null;)
{
如果(键<当前键)
{
cur=cur.left;
}
else if(key==cur.key)
{
返回电流;
}
else//key>cur.key
{
cur=cur.right;
}
}
返回null;
}
//xy
// / \ / \
//a y=>xc
// / \ / \
//b c a b
专用空心旋转体(节点xNode)
{
Node xPar=xNode.parent;
布尔值isRoot=xPar==null;
布尔值isLChild=!isRoot&&xPar.left==xNode;
Node yNode=xNode.right;
节点beta=yNode.left;
if(isRoot)root=yNode;
如果(isLChild)xPar.left=yNode,则为else;
else xPar.right=yNode;
yNode.parent=xPar;
yNode.left=xNode;
xNode.parent=yNode;
xNode.right=beta;
如果(beta!=null)beta.parent=xNode;
}
//y x
// / \ / \
//x c=>a y
// / \ / \
//a、b、c
专用空心旋转器(节点yNode)
{
节点yPar=yNode.parent;
布尔值isRoot=yPar==null;
布尔值isLChild=!isRoot&&yPar.left==yNode;
Node xNode=yNode.left;
节点beta=xNode.right;
如果(isRoot)root=xNode;
如果(isLChild)yPar.left=xNode,则为else;
else yPar.right=xNode;
xNode.parent=yPar;
xNode.right=yNode;
yNode.parent=xNode;
yNode.left=beta;
如果(beta!=null)beta.parent=yNode;
}
公共无效插入(int键)
{
if(root==null)
{
根=新节点(键);
返回;
}
节点PAR=NULL;
for(Node=root;Node!=null;)
{
PAR =节点;
if(键<节点键)
{
node=node.left;
}
else if(key>node.key)
{
node=node.right;
}
else//key==node.key
{
//无需执行任何操作,因为没有要更新的值。
返回;
}
}
//创建节点并设置指针。
Node newNode=新节点(键);
NeNoDe.Prime= PAR;
如果(key < PAR.Key)PAR.Le= NeNe结;
否则,右= NeNe结;
}
public int[]getInOrder()
{
if(root==null)返回新的int[]{};
堆栈=新堆栈();
ArrayList orderList=新建ArrayList();
对于(节点=根;;)
{
if(node==null)
{
if(stack.empty())中断;
node=stack.pop();
orderList.add(node.key);
node=node.right;
}
其他的
{
栈推(节点);
node=node.left;
}
}
int[]order=newint[orderList.size()];
for(int i=0;i
下面是测试另一个函数的代码:
import java.io.*;
import java.util.*;
public class Lab1
{
// ---------------------------------------------------------------------
// Do not change any of the code below!
private static final int LabNo = 4;
private static final String quarter = "Fall 2020";
private static final Random rng = new Random(190718);
private static boolean testProblem(int[][] testCase)
{
int[] arr1 = testCase[0];
int[] arr2 = testCase[1];
// --- Build tree ---
BST tree1 = new BST();
BST tree2 = new BST();
for (int i = 0; i < arr1.length; i++)
{
tree1.insert(arr1[i]);
tree2.insert(arr2[i]);
}
int[] pre2 = tree2.getPreOrder();
BST.problem(tree1, tree2);
// --- Verify tree. ---
int[] pre1 = tree1.getPreOrder();
int[] in1 = tree1.getInOrder();
if (in1.length != arr1.length) return false;
for (int i = 0; i < in1.length; i++)
{
if (in1[i] != i) return false;
if (pre1[i] != pre2[i]) return false;
}
return true;
}
public static void main(String args[])
{
System.out.println("CS 302 -- " + quarter + " -- Lab " + LabNo);
testProblems(1);
}
private static void testProblems(int prob)
{
int noOfLines = 100000;
System.out.println("-- -- -- -- --");
System.out.println(noOfLines + " test cases for problem " + prob + ".");
boolean passedAll = true;
long start = System.currentTimeMillis();
for (int i = 1; i <= noOfLines; i++)
{
boolean passed = false;
boolean exce = false;
try
{
int[][] testCase = createProblem(i);
passed = testProblem(testCase);
}
catch (Exception ex)
{
passed = false;
exce = true;
}
if (!passed)
{
System.out.println("Test " + i + " failed!" + (exce ? " (Exception)" : ""));
passedAll = false;
break;
}
}
System.out.println((System.currentTimeMillis() - start) + " ms");
if (passedAll)
{
System.out.println("All test passed.");
}
}
private static void shuffle(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++)
{
int rndInd = rng.nextInt(arr.length - i) + i;
int tmp = arr[i];
arr[i] = arr[rndInd];
arr[rndInd] = tmp;
}
}
private static int[][] createProblem(int testNo)
{
int size = rng.nextInt(Math.min(200, testNo)) + 1;
int[] numbers1 = new int[size];
int[] numbers2 = new int[size];
for (int i = 0; i < size; i++)
{
numbers1[i] = i;
numbers2[i] = i;
}
shuffle(numbers1);
shuffle(numbers2);
return new int[][] { numbers1, numbers2 };
}
}
import java.io.*;
导入java.util.*;
公共类Lab1
{
// ---------------------------------------------------------------------
//不要更改下面的任何代码!
专用静态最终int LabNo=4;
私人静态最终字符串季度=“2020年秋季”;
私有静态最终随机rng=新随机(190718);
私有静态布尔测试问题(int[]testCase)
{
int[]arr1=testCase[0];
int[]arr2=testCase[1];
//---建树---
BST tree1=新的BST();
BST tree2=新的BST();
//I understand this is quite late but this is more for people who look now for this help
public static void problem(BST tree1, BST tree2)
{
//if root is null then we've reached the end of a branch (base case)
if(tree1.root == null || tree2.root == null)
{
return;
}
//finding the node we need to rotate to tree1's root to match 2nd tree
Node match = tree1.find(tree2.getRootKey());
//loop to rotate matched node until it becomes tree1's new root or parent of the root
while(match != tree1.root && match != tree1.root.parent)
{
//parent node of matched node we need to get to new position
Node matchParent = match.parent;
//move matched node we want up the levels of tree1
//if matched node key is more than its parent then rotate parent left (which moves matched node up a level)
//otherwise rotate the parent right (still moves matched node up a level)
if(match.key > matchParent.key)
{
tree1.rotateL(matchParent);
}
else
{
tree1.rotateR(matchParent);
}
}
//if the matched node becomes the parent of tree1's root, in the loop above, then we need to
//change it so that the matched node is the root to line up with tree2
if(match == tree1.root.parent)
{
tree1.root = match;
}
// recursively go through left tree
// new BSTs to signify left subtrees
BST leftTree1 = new BST();
BST leftTree2 = new BST();
leftTree1.root = tree1.root.left;
leftTree2.root = tree2.root.left;
problem(leftTree1, leftTree2);
// recursively go through right tree
// new BSTs to signify right subtrees
BST rightTree1 = new BST();
BST rightTree2 = new BST();
rightTree1.root = tree1.root.right;
rightTree2.root = tree2.root.right;
problem(rightTree1, rightTree2);
}