Advertisement
anticlown

Threaded Binary Tree(3 sem)

Nov 20th, 2023 (edited)
890
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.44 KB | None | 0 0
  1. /*
  2.                                             #########################################
  3.                                             |           Node class start            |
  4.                                             #########################################
  5. */
  6. public class Node {
  7.     int key;
  8.     int height;
  9.     Node left;
  10.     Node right;
  11.     boolean rightThread; // Истина, если правый указатель указывает на преемника
  12.                         // Ложь, если правый указатель указывает на обычного потомка
  13.     boolean isOutputed;
  14.  
  15.     @Override
  16.     public String toString() {
  17.         return "" + key;
  18.     }
  19. }
  20. /*
  21.                                             #########################################
  22.                                             |           Node class end              |
  23.                                             #########################################
  24.  
  25.                                             #########################################
  26.                                             |           Tree class start            |
  27.                                             #########################################
  28. */
  29. class Tree {
  30.     public Node rootNode;
  31.  
  32.     /*      insert func start     */
  33.     public Node insertNode(Node parentNode, final int key) {
  34.         if (parentNode == null) {
  35.             Node temp = new Node();
  36.             temp.key = key;
  37.             return temp;
  38.         } else if (parentNode.key > key) {
  39.             parentNode.left = insertNode(parentNode.left, key);
  40.         } else if (parentNode.key < key) {
  41.             if (parentNode.rightThread) {
  42.                 parentNode.right = null;
  43.                 parentNode.rightThread = false;
  44.             }
  45.  
  46.             parentNode.right = insertNode(parentNode.right, key);
  47.         } else {
  48.             System.err.println("Некорректный ввод! Элемент с таким значением уже существует.");
  49.         }
  50.         return parentNode;
  51.     }
  52.     /*      insert func end     */
  53.  
  54.     /*      delete func start     */
  55.     public static Node mostLeftChild(final Node parentNode) {
  56.         Node temp = parentNode;
  57.         while (temp.left != null)
  58.             temp = temp.left;
  59.         return temp;
  60.     }
  61.  
  62.     public Node deleteNode(Node parentNode, final int key) {
  63.         if (parentNode == null) {
  64.             System.err.println("Элемента с таким значением нет в дереве!");
  65.             return null;
  66.         } else if (parentNode.key > key) {
  67.             parentNode.left = deleteNode(parentNode.left, key);
  68.         } else if (parentNode.key < key) {
  69.             parentNode.right = deleteNode(parentNode.right, key);
  70.         } else {
  71.             if (parentNode.left == null || parentNode.right == null || (parentNode.rightThread)) {
  72.                 parentNode = (parentNode.left == null && !parentNode.rightThread) ? parentNode.right : parentNode.left;
  73.             } else {
  74.                 Node mostLeftChild = mostLeftChild(parentNode.right);
  75.                 parentNode.key = mostLeftChild.key;
  76.                 parentNode.right = deleteNode(parentNode.right, parentNode.key);
  77.             }
  78.         }
  79.         return parentNode;
  80.     }
  81.     /*      delete func end     */
  82.  
  83.     /*      find func start     */
  84.     public Node findNodeByValue(final int value) {
  85.         Node currentNode = rootNode;
  86.         while (currentNode.key != value) {
  87.             if (value < currentNode.key) {
  88.                 currentNode = currentNode.left;
  89.             } else {
  90.                 currentNode = currentNode.right;
  91.             }
  92.             if (currentNode == null) {
  93.                 System.out.println("Элемента с таким значением нет в дереве.");
  94.                 return null;
  95.             }
  96.         }
  97.         return currentNode;
  98.     }
  99.     /*      find func end     */
  100.  
  101.     /*      thread func start     */
  102.     public static Node clearThreadsAndOutputs(Node parentNode) {
  103.         if (parentNode == null)
  104.             return null;
  105.         clearThreadsAndOutputs(parentNode.left);
  106.         parentNode.isOutputed = false;
  107.         if (parentNode.rightThread) {
  108.             parentNode.right = null;
  109.             parentNode.rightThread = false;
  110.         }
  111.         clearThreadsAndOutputs(parentNode.right);
  112.         return null;
  113.     }
  114.  
  115.     public static Node sewTree(Node parentNode) {
  116.         if (parentNode == null) {
  117.             return null;
  118.         }
  119.  
  120.         if (parentNode.right == null && parentNode.left == null) {
  121.             return parentNode;
  122.         }
  123.  
  124.         if (parentNode.left != null) {
  125.             Node left = sewTree(parentNode.left);
  126.             left.right = parentNode;
  127.             left.rightThread = true;
  128.         }
  129.  
  130.         if (parentNode.right == null) {
  131.             return parentNode;
  132.         }
  133.  
  134.         return sewTree(parentNode.right);
  135.     }
  136.     /*      thread func end     */
  137.  
  138.     /*      print methods start     */
  139.     public static final String ANSI_RESET = "\u001B[0m";
  140.     public static final String ANSI_BLUE = "\u001B[34m";
  141.     public static final String ANSI_RED = "\u001B[31m";
  142.  
  143.     void printInorder(Node parentNode) {
  144.         if (parentNode == null)
  145.             return;
  146.  
  147.         printInorder(parentNode.left);
  148.         String color = (parentNode.rightThread) ? ANSI_RED : ANSI_BLUE;
  149.         System.out.print(color + parentNode.key + " " + ANSI_RESET);
  150.         if (!parentNode.rightThread)
  151.             printInorder(parentNode.right);
  152.     }
  153.  
  154.     void printPreorder(Node parentNode) {
  155.         if (parentNode == null)
  156.             return;
  157.  
  158.         String color = (parentNode.rightThread) ? ANSI_RED : ANSI_BLUE; //useless at the moment
  159.         System.out.print(color + parentNode.key + " " + ANSI_RESET);
  160.         printPreorder(parentNode.left);
  161.         if (!parentNode.rightThread)
  162.             printPreorder(parentNode.right);
  163.     }
  164.  
  165.     void printPostorder(Node parentNode) {
  166.         if (parentNode == null)
  167.             return;
  168.  
  169.         printPostorder(parentNode.left);
  170.         if (!parentNode.rightThread)
  171.             printPostorder(parentNode.right);
  172.         String color = (parentNode.rightThread) ? ANSI_RED : ANSI_BLUE; //useless at the moment
  173.         System.out.print(color + parentNode.key + " " + ANSI_RESET);
  174.     }
  175.  
  176.  
  177.     static public void printSewTree(Node currNode) {
  178.         if (currNode != null) {
  179.             String color = (currNode.right != null && currNode.right.isOutputed) ? ANSI_RED : ANSI_BLUE; //useless at the moment
  180.             System.out.print(color + currNode.key + " " + ANSI_RESET);
  181.             if (!currNode.isOutputed) {
  182.                 currNode.isOutputed = true;
  183.                 printSewTree(currNode.left);
  184.                 printSewTree(currNode.right);
  185.             }
  186.         }
  187.     }
  188.  
  189.     public void printNode(final Node currentNode) {
  190.         System.out.println("Выбранный узел имеет значение: " + currentNode.key);
  191.         if (currentNode.left == null && currentNode.right == null)
  192.             System.out.println("У данного элемента нет потомков.");
  193.         else {
  194.             String ansRightChild = (currentNode.right != null) ? "Значение правого потомка: " + currentNode.right.key : "У данного элемента нет правого потомка.";
  195.             System.out.println(ansRightChild);
  196.             String ansLeftChild = (currentNode.left != null) ? "Значение левого потомка: " + currentNode.left.key : "У данного элемента нет левого потомка.";
  197.             System.out.println(ansLeftChild);
  198.         }
  199.     }
  200.     /*      print methods end     */
  201. }
  202.  
  203. /*
  204.                                             #########################################
  205.                                             |           Tree class end              |
  206.                                             #########################################
  207.  
  208.                                             #########################################
  209.                                             |         TreePrinter class start       |
  210.                                             #########################################
  211. */
  212.  
  213. import java.util.ArrayList;
  214. import java.util.List;
  215.  
  216. public class TreePrinter
  217. {
  218.     public static void printTree(Node root)
  219.     {
  220.         List<List<String>> lines = new ArrayList<List<String>>();
  221.  
  222.         List<Node> level = new ArrayList<Node>();
  223.         List<Node> next = new ArrayList<Node>();
  224.  
  225.         level.add(root);
  226.         int newNode = 1;
  227.  
  228.         int widest = 0;
  229.  
  230.         while (newNode != 0) {
  231.             List<String> line = new ArrayList<String>();
  232.  
  233.             newNode = 0;
  234.  
  235.             for (Node currNode : level) {
  236.                 if (currNode == null) {
  237.                     line.add(null);
  238.  
  239.                     next.add(null);
  240.                     next.add(null);
  241.                 } else {
  242.                     String stringOfNode = currNode.toString();
  243.                     line.add(stringOfNode);
  244.                     if (stringOfNode.length() > widest) widest = stringOfNode.length();
  245.  
  246.                     next.add(currNode.left);
  247.                     if (!currNode.rightThread)
  248.                         next.add(currNode.right);
  249.                     else {
  250.                         next.add(null);
  251.                     }
  252.  
  253.                     if (currNode.left != null) newNode++;
  254.                     if (!currNode.rightThread && currNode.right != null) newNode++;
  255.                 }
  256.             }
  257.  
  258.             if (widest % 2 == 1) widest++;
  259.  
  260.             lines.add(line);
  261.  
  262.             List<Node> tmp = level;
  263.             level = next;
  264.             next = tmp;
  265.             next.clear();
  266.         }
  267.  
  268.         int perPiece = lines.get(lines.size() - 1).size() * (widest + 4);
  269.         for (int i = 0; i < lines.size(); i++) {
  270.             List<String> line = lines.get(i);
  271.             int hpw = (int) Math.floor(perPiece / 2f) - 1;
  272.  
  273.             if (i > 0) {
  274.                 for (int j = 0; j < line.size(); j++) {
  275.  
  276.                     char tempChar = ' ';
  277.                     if (j % 2 == 1) {
  278.                         if (line.get(j - 1) != null) {
  279.                             tempChar = (line.get(j) != null) ? '┴' : '┘';
  280.                         } else {
  281.                             if (line.get(j) != null) tempChar = '└';
  282.                         }
  283.                     }
  284.                     System.out.print(tempChar);
  285.  
  286.                     if (line.get(j) == null) {
  287.                         for (int k = 0; k < perPiece - 1; k++) {
  288.                             System.out.print(" ");
  289.                         }
  290.                     } else {
  291.                         for (int k = 0; k < hpw; k++) {
  292.                             System.out.print(j % 2 == 0 ? " " : "─");
  293.                         }
  294.                         System.out.print(j % 2 == 0 ? "┌" : "┐");
  295.                         for (int k = 0; k < hpw; k++) {
  296.                             System.out.print(j % 2 == 0 ? "─" : " ");
  297.                         }
  298.                     }
  299.                 }
  300.                 System.out.println();
  301.             }
  302.  
  303.             for (String lineStr : line) {
  304.  
  305.                 if (lineStr == null) lineStr = "";
  306.                 float tmp = perPiece / 2f - lineStr.length() / 2f;
  307.                 int gap1 = (int) Math.ceil(tmp);
  308.                 int gap2 = (int) Math.floor(tmp);
  309.  
  310.                 for (int k = 0; k < gap1; k++) {
  311.                     System.out.print(" ");
  312.                 }
  313.                 System.out.print(lineStr);
  314.                 for (int k = 0; k < gap2; k++) {
  315.                     System.out.print(" ");
  316.                 }
  317.             }
  318.             System.out.println();
  319.  
  320.             perPiece /= 2;
  321.         }
  322.     }
  323. }
  324.  
  325. /*
  326.  
  327.                                             #########################################
  328.                                             |         TreePrinter class end         |
  329.                                             #########################################
  330.  
  331.                                             #########################################
  332.                                             |           Main class start            |
  333.                                             #########################################
  334. */
  335.  
  336. import java.util.Scanner;
  337.  
  338. public class Main {
  339.  
  340.     public static void printTaskInfo() {
  341.         System.out.println("\tДанная программа позволяет сформировать, изменить, вывести и прошить бинарное дерево поиска.");
  342.         System.out.println("\t\tДля работы в программе используйте команды меню.");
  343.     }
  344.  
  345.     public static void printMenuOptions() {
  346.         System.out.println("\t\t\t\t\t Меню");
  347.         System.out.println("\t\t\t\t1.Добавить узел");
  348.         System.out.println("\t\t\t\t2.Удалить узел");
  349.         System.out.println("\t\t\t\t3.Поиск узла");
  350.         System.out.println("\t\t\t\t4.Вывести дерево");
  351.         System.out.println("\t\t\t\t5.Прошить дерево и вывести прошивку");
  352.         System.out.println("\t\t\t\t6.Вывести обходы дерева всеми способами.");
  353.         System.out.println("\t\t\t\t7.Выйти из программы");
  354.     }
  355.  
  356.     public static void main(String[] args) {
  357.         Tree tree = new Tree();
  358.         Scanner scan = new Scanner(System.in);
  359.         int choice = 0;
  360.  
  361.         printTaskInfo();
  362.         printMenuOptions();
  363.  
  364.         do {
  365.             System.out.print("\n\nВведите команду для выполнения: ");
  366.             try {
  367.                 choice = Integer.parseInt(scan.nextLine());
  368.             } catch (Exception e) {
  369.                 choice = -1;
  370.             }
  371.             switch (choice) {
  372.                 case 1: {
  373.                     System.out.println("Вы выбрали: добавить узел");
  374.                     int elemToAdd;
  375.                     System.out.print("Введите значение элемента для добавления: ");
  376.                     elemToAdd = Integer.parseInt(scan.nextLine());
  377.                     tree.rootNode = tree.insertNode(tree.rootNode, elemToAdd);
  378.                     break;
  379.                 }
  380.  
  381.                 case 2: {
  382.                     System.out.println("Вы выбрали: удалить узел");
  383.                     int elemToDelete;
  384.                     System.out.print("Введите значение элемента для удаления: ");
  385.                     elemToDelete = Integer.parseInt(scan.nextLine());
  386.                     tree.rootNode = tree.deleteNode(tree.rootNode, elemToDelete); //? "Элемент успешно удален!" : "Элемента с таким значением нет в дереве!";
  387.                     break;
  388.                 }
  389.                 case 3: {
  390.                     System.out.println("Вы выбрали: поиск узла");
  391.                     int elemToFind;
  392.                     System.out.print("Введите значение элемента для поиска: ");
  393.                     elemToFind = Integer.parseInt(scan.nextLine());
  394.                     Node foundNode = tree.findNodeByValue(elemToFind);
  395.                     if (foundNode != null)
  396.                         tree.printNode(foundNode);
  397.                     break;
  398.                 }
  399.                 case 4: {
  400.                     System.out.println("Вы выбрали: вывести дерево");
  401.                     System.out.println("Вывод дерева: ");
  402.                     TreePrinter.printTree(tree.rootNode);
  403.                     break;
  404.                 }
  405.                 case 5: {
  406.                     System.out.println("Вы выбрали: прошить дерево и вывести прошивку.\nКрасным цветом обозначены узлы, имеющие прошивку");
  407.                     Tree.clearThreadsAndOutputs(tree.rootNode);
  408.                     Tree.sewTree(tree.rootNode);
  409.                     Tree.printSewTree(tree.rootNode);
  410.                     break;
  411.                 }
  412.                 case 6: {
  413.                     System.out.println("Вы выбрали: показать обход дерева всеми способами.");
  414.                     System.out.println("Прямой обход: ");
  415.                     tree.printPreorder(tree.rootNode);
  416.                     System.out.println("\nСимметричный обход: ");
  417.                     tree.printInorder(tree.rootNode);
  418.                     System.out.println("\nОбратный обход: ");
  419.                     tree.printPostorder(tree.rootNode);
  420.                     break;
  421.                 }
  422.                 case 7: {
  423.                     System.out.println("Вы выбрали: выйти из программы");
  424.                     break;
  425.                 }
  426.                 default:
  427.                     System.err.println("Некорректный ввод! Выберите один из пунктов меню!");
  428.                     break;
  429.             }
  430.         } while (choice != 7);
  431.     }
  432. }
  433.  
  434. /*
  435.                                             #########################################
  436.                                             |           Main class end              |
  437.                                             #########################################
  438. */
  439.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement