Advertisement
Guest User

Untitled

a guest
Apr 9th, 2020
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.95 KB | None | 0 0
  1. public class BacktrackingBST implements Backtrack, ADTSet<BacktrackingBST.Node> {
  2.     private Stack stack;
  3.     private Stack redoStack;
  4.     BacktrackingBST.Node root = null;
  5.  
  6.     // Do not change the constructor's signature
  7.     public BacktrackingBST(Stack stack, Stack redoStack) {
  8.         this.stack = stack;
  9.         this.redoStack = redoStack;
  10.     }
  11.  
  12.     public Node getRoot() {
  13.         return root;
  14.     }
  15.    
  16.     public Node search(int x) {
  17.         Node current = getRoot();
  18.         while (current!=null){
  19.             if (current.getKey()==x) return current;
  20.             else if (current.getKey()>x){
  21.                 current=current.left;
  22.             }
  23.             else {
  24.                 current = current.right;
  25.             }
  26.  
  27.         }
  28.         return null;
  29.  
  30.     }
  31.  
  32.     public void insert(BacktrackingBST.Node z) {
  33.         Node current = root;
  34.         Node parent = null;
  35.         while (current!=null){
  36.             parent = current;
  37.             if (current.getKey()>z.getKey()){
  38.                 current=current.left;
  39.             }
  40.             else {
  41.                 current = current.right;
  42.             }
  43.         }
  44.         if (parent == null){
  45.             root = z;
  46.             z.setParent(null);
  47.         }
  48.         else if (parent.getKey()>z.getKey()){
  49.             parent.left =z ;
  50.             z.setParent(parent);
  51.         }
  52.         else {
  53.             parent.right = z;
  54.             z.setParent(parent);
  55.         }
  56.         stack.push(new BacktrackAction(true,z,z,-1));
  57.  
  58.     }
  59.  
  60.     public void delete(Node x) {
  61.         Node xCopy = new Node(x); // create a copy of x for backtracking.
  62.         int id = x.sideCheck(); // check whether x is a right child, left child, or the root.
  63.         int deleteCase; // will be used for backtracking
  64.         if (x.right == null & x.left == null){ // case 1: x is a leaf
  65.             deleteCase=1;
  66.             stack.push(new BacktrackAction(false,xCopy,x,deleteCase)); // push backtrack action into the stack
  67.             if (id==0){
  68.                 root = null;
  69.             }
  70.             else if (id==1){
  71.                 x.getParent().right=null;
  72.             }
  73.             else {
  74.                 x.getParent().left = null;
  75.             }
  76.         }
  77.         else if (x.right == null | x.left == null){    // case 2 : x has only one child.
  78.             deleteCase = 2;
  79.             stack.push(new BacktrackAction(false,xCopy,x,deleteCase)); // push backtrack action into the stack
  80.             if (x.right == null){ // following actions in this code block will delete x and make his child - his parent's child, and his child's parent - his parent.
  81.                 x.left.setParent(x.getParent());
  82.                 if (id==0){
  83.                     root = x.left;
  84.                 }
  85.                 else if (id == 1){
  86.                     x.getParent().right = x.left;
  87.                 }
  88.                 else x.getParent().left = x.left;
  89.             }
  90.             else { // following actions in this code block will delete x and make his child - his parent's child, and his child's parent - his parent.
  91.                 x.right.setParent(x.getParent());
  92.                 if (id==0){
  93.                     root = x.right;
  94.                 }
  95.                 else if (id == 1){
  96.                     x.getParent().right = x.right;
  97.                 }
  98.                 else x.getParent().left = x.right;
  99.             }
  100.         }
  101.         else { // following actions in this code block will delete the successor of x and replace x with it.
  102.             deleteCase = 3;
  103.             Node suc = successor(x);
  104.             Node replace = new Node(suc);
  105.             delete(suc); // delete the successor of x because x will be replaced with it.
  106.             stack.push(new BacktrackAction(false,xCopy,x,deleteCase));// push backtrack action into the stack
  107.             x.replace(replace);
  108.         }
  109.  
  110.     }
  111.  
  112.     public Node minimum() {
  113.         Node output = getRoot();
  114.         if (output!=null){
  115.             while (output.left != null){
  116.                 output = output.left;
  117.             }
  118.         }
  119.         return output;
  120.     }
  121.  
  122.     public Node maximum() {
  123.         Node output = getRoot();
  124.         if (output!=null){
  125.             while (output.right != null){
  126.                 output = output.right;
  127.             }
  128.         }
  129.  
  130.         return output;
  131.     }
  132.  
  133.     public Node successor(Node x) {
  134.         if (x.right!=null){
  135.             Node output = x.right;
  136.             while (output.left!=null){
  137.                 output = output.left;
  138.             }
  139.             return output;
  140.         }
  141.         else {
  142.             Node output = x;
  143.             while (output.getParent().right == output){
  144.                 output=output.getParent();
  145.             }
  146.             return output.getParent();
  147.         }
  148.     }
  149.  
  150.     public Node predecessor(Node x) {
  151.         Node output = x.left;
  152.         if (output!=null){
  153.             while (output.right!=null){
  154.                 output = output.right;
  155.             }
  156.         }
  157.         return output;
  158.     }
  159.  
  160.     @Override
  161.     public void backtrack() {
  162.         BacktrackAction bk = (BacktrackAction)stack.pop(); // check what the last action was.
  163.         if (bk.isInsert()){ // if last action was an insert, just delete the inserted element.
  164.             delete(bk.getPointer());
  165.             stack.pop(); // get rid of the redundant delete action that was pushed into the stack while deleting.
  166.         }
  167.         else {
  168.             int id = bk.getNode().sideCheck();
  169.             if (bk.getDeleteCase()==1){
  170.                 if (id==0){
  171.                     root = bk.getNode();
  172.                 }
  173.                 else if (id==1){
  174.                     bk.getNode().getParent().right=bk.getNode();
  175.                 }
  176.                 else {
  177.                     bk.getNode().getParent().left=bk.getNode();
  178.                 }
  179.             }
  180.             else if (bk.getDeleteCase()==2){
  181.                 if (id==0){
  182.                     root.setParent(bk.getNode());
  183.                     root = bk.getNode();
  184.                 }
  185.                 else  if (id == 1){
  186.                     bk.getNode().getParent().right=bk.getNode();
  187. //                    bk.getNode().getParent().right.setParent(bk.getNode());
  188.                     if (bk.getNode().right!=null){
  189.                         bk.getNode().right.setParent(bk.getNode());
  190.                     }
  191.                     if (bk.getNode().left!=null){
  192.                         bk.getNode().left.setParent(bk.getNode());
  193.                     }
  194.  
  195.  
  196.                 }
  197.                 else {
  198.                     bk.getNode().getParent().left=bk.getNode();
  199.                     if (bk.getNode().right!=null){
  200.                         bk.getNode().right.setParent(bk.getNode());
  201.                     }
  202.                     if (bk.getNode().left!=null){
  203.                         bk.getNode().left.setParent(bk.getNode());
  204.                     }
  205.                 }
  206.  
  207.             }
  208.             else {
  209.                 if (id==0){
  210.                     root.replace(bk.getNode());
  211.                     backtrack();
  212.  
  213.                 }
  214.                 else if (id==1){
  215.                     bk.getNode().getParent().right.replace(bk.getNode());
  216.                     backtrack();
  217.  
  218.                 }
  219.                 else{
  220.                     bk.getNode().getParent().left.replace(bk.getNode());
  221.                     backtrack();
  222.  
  223.                 }
  224.             }
  225.         }
  226.     }
  227.  
  228.     @Override
  229.     public void retrack() {
  230.  
  231.     }
  232.  
  233.     public void printPreOrder(){
  234.         printTree(getRoot());
  235.     }
  236.     public void printTree (BacktrackingBST.Node node) {
  237.         System.out.print(node.getKey() + " ");
  238.         if (node.left != null)
  239.             printTree(node.left);
  240.         if (node.right != null)
  241.             printTree(node.right);
  242.     }
  243.  
  244.  
  245.     @Override
  246.     public void print() {
  247.         printPreOrder();
  248.     }
  249.  
  250.     public static class Node{
  251.         //These fields are public for grading purposes. By coding conventions and best practice they should be private.
  252.         public BacktrackingBST.Node left;
  253.         public BacktrackingBST.Node right;
  254.        
  255.         private BacktrackingBST.Node parent;
  256.         private int key;
  257.         private Object value;
  258.  
  259.         public Node(int key, Object value) {
  260.             this.key = key;
  261.             this.value = value;
  262.         }
  263.         public Node(Node toCopy){
  264.             this.left = toCopy.left;
  265.             this.right = toCopy.right;
  266.             this.parent = toCopy.parent;
  267.             this.key = toCopy.key;
  268.             this.value = toCopy.value;
  269.  
  270.         }
  271.  
  272.         public Node getParent() {
  273.             return parent;
  274.         }
  275.  
  276.         public void setParent(Node parent) {
  277.             this.parent = parent;
  278.         }
  279.  
  280.         public int getKey() {
  281.             return key;
  282.         }
  283.  
  284.         public Object getValue() {
  285.             return value;
  286.         }
  287.         public void replace(Node replace){
  288.             this.key = replace.getKey();
  289.             this.value = replace.value;
  290.         }
  291.         public int sideCheck(){
  292.             if (this.getParent()==null) return 0;
  293.             if (this.getKey()>this.getParent().getKey())return 1; // right child
  294.             else return -1; //left child
  295.         }
  296.  
  297.         @Override
  298.         public String toString() {
  299.             return ""+key ;
  300.         }
  301.     }
  302.  
  303.     private static class BacktrackAction{
  304.         private boolean isInsert;
  305.         private Node node;
  306.         private Node pointer;
  307.         private int deleteCase;
  308.  
  309.         public BacktrackAction(boolean isInsert, Node node , Node pointer, int deleteCase) {
  310.             this.isInsert = isInsert;
  311.             this.node = node;
  312.             this.pointer = pointer;
  313.             this.deleteCase = deleteCase;
  314.         }
  315.  
  316.         public boolean isInsert() {
  317.             return isInsert;
  318.         }
  319.  
  320.         public Node getNode() {
  321.             return node;
  322.         }
  323.  
  324.         public int getDeleteCase() {
  325.             return deleteCase;
  326.         }
  327.  
  328.         public Node getPointer() {
  329.             return pointer;
  330.         }
  331.  
  332.         public void setPointer(Node pointer) {
  333.             this.pointer = pointer;
  334.         }
  335.     }
  336.     public void treeFormPrint(){
  337.         if (root != null) treeFormPrint(root, "");
  338.         else System.out.println("Empty tree");
  339.     }
  340.  
  341.     // TODO remove
  342.     private void treeFormPrint(Node node, String acc){
  343.         String signSpace = acc + "            ";
  344.         if (node.right != null) {
  345.             treeFormPrint(node.right, acc+"               ");
  346.             if (node.right.parent == node)
  347.                 System.out.println(signSpace + "/");
  348.             else System.out.println(signSpace + "$");
  349.         }
  350.         System.out.println(acc + "| key: " + node.key);
  351.         System.out.println(acc + "| par: " + node.parent);
  352.         if (node.left != null) {
  353.             if (node.left.parent == node)
  354.                 System.out.println(signSpace + "\\");
  355.             else System.out.println(signSpace + "$");
  356.             treeFormPrint(node.left, acc+"               ");
  357.         }
  358.     }
  359.  
  360. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement