## Search Binary Tree

Search for a binary tree: For any node searching for a binary tree, the value of the left subtree is smaller than the node, and the value of the right subtree is larger than it.

In TreeMap, key-value is provided as in HashMap, and keys are sorted in size order.The middle way is to search for knowledge of binary trees.

A balanced search Binary tree:

### AVL Tree - Strictest Balance

The left subtree and the right subtree of any node are not higher than 1, and the complexity is O(logN).This results in very frequent adjustments.

### Red and Black Trees - Strict Balance Requirements

Each node is colored, and the head and leaf nodes must be black. Neighboring two nodes cannot have consecutive red nodes. For any chain, the number of black nodes differs by less than 1. Therefore, the height difference between the longest and shortest chains of any chain is not more than 1 times.

### Search Binary Tree Code

Need to be able to add, delete, and change checks, without considering balance at this time

public class BinarySearchTree{ //root node public Node root; //The size of the tree protected int size; //Functions of Binary Tree Finding public Node search(int element){ Node node = root; //Return node if it is found at last, or node if it does not exist as null while(node != null && node.value != null && node.value != element){ if(element < node.value){ node = node.left }else{ node = node.right; } } return node; } //Insert, add functionality public Node insert(int element){ if(root == null){ root = createNode(element,null,null,null); size++; return root; } Node insertParentNode = null; Node searchTempNode = root; //insertParentNode goes down until it reaches the leaf node while(searchTempNode != null && searchTEmpNode.value != null){ insertParentNode = searchTempNode; if(element < searchTempNode.value){ searchTempNode = searchTempNode.left; }else{ searchTempNode = searchTempNode.right; } } //Compare the value to be inserted with the current node, and if it is smaller than the current node, it is placed to the left of the current node, otherwise it is placed to the right of the current node. Node newNode = createNode(element,insertParentNode,null,null); if(insertParentNode.value > newNode.value){ insertParentNode.left = newNode; }else{ insertParentNode.right = newNode; } size++; return newNode; } //Delete function /** Deletion is cumbersome. If only a left subtree exists for a deleted node, then the position of the left child node of the node can be directly replaced. Similarly, if only a right subtree exists, the right child node can be directly replaced. //If the nodes deleted at this time are both left and right subtrees, then the left-most node of the right subtree is top to the deleted node. If the left-most node of the right subtree has a right subtree at this time, the right subtree is transferred to its parent node

### Search Binary Tree Add Balance

For balance in search Binary trees, both left-hand and right-hand adjustments are made for binary trees. Different search binary trees are just combinations of left-hand and right-hand actions.Adjust the height of the whole search binary tree to achieve balance.

The mechanisms by which AVL finds imbalances:

When a binary tree is deleted and added, it may cause an unbalanced binary tree.

When adding or deleting: In addition to adding node information for the whole binary tree, you also need to add maximum height information for left and right subtrees. When inserting a value, if the height of a subtree of the tree changes, the maximum height information stored by the parent node will be updated at this time, until the following node, and then followThe second judgment is whether the height is consistent or at most 1 difference. If it is not satisfied, the left or right rotation will occur to make it balance.

Adjust combination types: LL, RR, LR, RL

LL (longer left): Simply go right at this point

RR (longer right): Simply turn left at this point

RL (longer left on right): first turn left node on right into parent node, then turn right

LR (longer left right): first turn the right left node into the parent node, then turn left

### AVL Tree Adjustment Balance Code

The AVL tree inherits the original node type, but adds a height.

public void rebalance(AVLNode node){ while(node != null){ Node parent = node.parent; int leftHeight = (node.left == null)? -1:((AVLNode) node.left).height; int rightHeight = (node.right == null) ? -1 : ((AVLNode)node.right).height; int nodeBalance = rightHeight -leftHeight; if(nodeBalance == 2){ if(node.right.right != null){ node = (AVLNode)avlRotateLeft(node); break; }else{ node = (AVLNode)doubleRotateRightLeft(node); break; } //The left tree is now overrun }else if(nodeBalance == -2){ //This judgement is LL type if(node.left.left != null){ //Only one right-handed operation is performed at this time node = (AVLNode)avlRotateRight(node); break; }else{ node = (AVLNode)doubleRotateLeftRight(node); break; } }else{ updateHeight(node); } node = (AVLNode)parent; } } //To establish the height of this tree, adjust it up from the node to see if it is balanced. private static final void updateHeight(AVLNode node){ int leftHeight = (node.left == null) ? -1:((AVLNode) node.left).height; int rightHeight = (node.right == null) ? -1:((AVLNode) node.right).height; node.height = 1+ Math.max(leftHeight,rightHeight); }

### Application of Red and Black Trees

- Using a procedure that contains the contents of a hash table, you can use treeMap.containsKey(i) to return whether the key is 5.You can also treeMap.get(i) to take out the value for I.
- There is a more convenient way to get content than in a hash table: treeMap.lastKey(), which gets the largest key. The process of getting the largest key only requires a right-hand node along the way with O(logN), treeMap.ceilingKey(k) to find the number equal to K in the entire binary tree, and if not, the smallest value greater than k.treeMap.floorKey(k) is looking for the maximum value less than or equal to K.All of these uses are many times faster than traditional hash tables.

### Example 1

#### Ideas:

- Split each matrix, the first [1, 3, 3] into (1, 3, up) and (3, 3, down), the third into (5, 1, up) and (6, 1, down)
- The positions are sorted from small to large, and the change in outline means that the lower height is covered by the higher height, after which the outline appears.
- Set up a treeMap and divide the building information into two parts, one is location, height, increase, the other is location, height, decrease.In this case, the key is saved as a height line in the map, and the value is several lines at a height.
- New nodes are created in the treeMap as you traverse the entire matrix, so you can know if the maximum height has changed to determine whether the current position produces a contour.As long as the top increases, the bottom decreases, so when a matrix is passed, the number of times information is zero and the corresponding node is deleted.

#### Code

//Node Format and Content public static class Node{ public boolean be; public int p; public int h; public Node(boolean boRe,int position,int height){ be = bORe; p = position; h = height; } } public static class NodeComparator implements Comparator<Node> { @Override public int compare(Node o1,Node o2){ if(o1.p != o2.p){ return o1.p-o2.p; } if(o1.be != o2.be){ return o1.be ? -1:1; } return 0; } } public static List<List<Integer>> buildingOutline(int[][] buildings){ Node[] nodes = new Node[buildings.length *2]; for(int i =0;i<buildings.length;i++){ //When placed, collect information up and down nodes[i *2] = new Node(true,buildings[i][0],building[i][2]); nodes[i*2+1] = new Node(false,buildings[i][1],buildings[i][2]); } //Sort by strict position Arrays.sort(nodes,new NodeComparator()); //htMap tags the maximum height information, and pmMap records the maximum height that each location rushes to //key is height information, value is number of occurrences TreeMap<Integer,Integer> htMap = new TreeMap<>(); //The key is the location and is strictly in ascending order when traversing the pmMap TreeMap<Integer,Integer> pmMap = new TreeMap<>(); for(int i = 0;i<nodes.length;i++){ //Judging up or down if(nodes[i].be){ //If the height first appears, place the current node in if(!htMap.containsKey(nodes[i].h)){ htMap.put(nodes[i].h,1); }else{ //If it happens before, then the number of times + 1 will occur at this time htMap.put(nodes[i].h,htMap.get(nodes[i].h)+1); } }else{ //This is a downward situation if(htMap.containsKey(nodes[i].h)){ //If the current height is 1, then subtract 1, you need to remove the current node if(htMap.get(nodes[i].h) == 1){ htMap.remove(nodes[i].h); }else{ //Height greater than 1 decreases height by one htMap.put(nodes[i].h,htMap.get(nodes[i].h)-1); } } } if(htMap.isEmpty()){ pmMap.put(nodes[i].p,0); }else{ pmMap.put(nodes[i].p,htMap.lastKey()); } } List<List<Integer>> res = new ArrayList<>(); int start = 0; int height = 0; //Because it is a treeMap, the current position is taken out in ascending order for(Entry<Integer,Integer> entry : pmMap.entrySet()){ int curPosition = entry.getKey(); int curMaxHeight = entry.getValue(); //If the previous height is different from the newly extracted height, it means that the contour is generated at this time if(height != curMaxHeight){ //If the previous height is 0, it means opening a new outline at this time, skipping if and setting the start position and height directly //If the height is different and not zero, the start position and height are also set if(height != 0){ //Form the entire outline List<Integer> newRecord = new ArrayList<Integer>(); newRecord.add(start); newRecord.add(curPosition); newRecord.add(height); res.add(newRecord); } start = curPosition; height = curMaxheight; } } return res; }

### Example 2

Given an array arr, there are 0, positive and negative values in the array, given an aim value, sum up and make the longest child array of the given value.

Once a continuous subarray, substring, etc. occurs, the longest subarray must be in it once the longest subarray that must end at each location is found

#### thinking

Sum is used to represent the sum of all the numbers accumulated from 0 to the current position. At the end of the current position, where sum-aim first appears is calculated, the array is the longest subarray ending at the current position, and then the current position ++, is calculated again.

Personal idea: Set up a new array, arr1, without considering spatial complexity, where the original array is summed from position 0, and then calculate if the sum-aim value has ever appeared in the previous array.

Left God algorithm: set up a map, where each value is stored in the map at its earliest occurrence, 0 this additive and appearing at the -1 position, and then store the values and their corresponding locations in the map, all the same as I thought.

#### Code

public static int maxLength(int[] arr,int aim){ if(arr == null || arr.length == 0){ return 0; } HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); map.put(0,-1); int len = 0; int sum = 0; for(int i = 0;i< arr.length; i++){ sum += arr[i]; if(map.containsKey(sum-aim)){ len = Math.max(i-map.get(sum-aim),len); } if(!map.containsKey(sum)){ map.put(sum,i); } } return len; }

### Example 3

Given an array, find the longest subarray with the same number of odd and even numbers in the array

Turn odd numbers to 1, even numbers to -1, so that the aim is equal to 0, and you get the corresponding result from Question 2.

### Example 4

#### thinking

Find at most a few subarrays with XOR 0 on the range of 0-i, and then 0-i+1 next time.

Assuming there is an optimal partition, then:

If I is not in the subarray of partitions for optimal partitioning, then the maximum number of subarrays for the 0-i range is the same as that on 0-(i-1).

If the position of i is in a sub-array with XOR and 0, and the last sub-array starts with k, it means that the position of K must be the nearest XOR and 0 to i.In this case, the optimal array is the optimal score group at the previous location plus one.So the title is converted to find the K position, where the optimal number of K positions is the same before the current position. In this case, the title is converted to find the latest position in the entire array that is XOR 0 to the current position.

#### Code

public static int mostEOR(int[] arr){ int ans = 0; int xor = 0; int[] mosts = new int[arr.length]; HashMap<Integer,Integer> map = new HashMap<>(); map.put(0,-1); for(int i = 0;i<arr.length;i++){ xor ^= arr[i]; if(map.containsKey(xor)){ int pre = map.get(xor); most[i] = pre == -1 ? 1: (mosts[pre] +1); } if(i >0){ mosts[i] = Math.max(mosts[i-1],mosts[i]); } map.put(xor,i); ans = Math.max(ans,mosts[i]); } return ans； }