Java 使一棵树与另一棵树相等的BST旋转

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 { /** *

我有一个问题: 您将获得两个非空的二叉搜索树T1和T2。T1和T2存储相同的键。然而,这两棵树的结构是不同的。实现一个算法,使用T1上的旋转使其等效于T2。也就是说,两棵树应该具有相同的结构。请注意,您只允许使用旋转,并且只允许在T1上使用;不允许以任何其他方式修改树

如果有人能帮助我朝着正确的方向实施这项计划,我将非常感激。这是到目前为止的代码


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);
}