How can I resume to show the preorder bst? - java

In my preious version of random to generate some value to array of node, it will be export the number of nodes and show the result after using BST. Then, my question is after I added scanner to input value by manually, it can't export the nodes with postorder now.
Before :
Inserting 9 nodes:
80 65 74 90 32 30 57 31 41
BST - size: 9 height: 4
30 31 32 41 57 65 74 80 90
After added insert :
Enter the number of the data: 5
Enter the values:
4
36
42
12
34
Inserted: [4, 36, 42, 12, 34]
It used postorder.
BinarySearchTree - size: 1 height: 0
trees.BSTree#30dae81
5
I expect:
Enter the number of the data: 5
Enter the values:
4
36
42
12
34
Inserted: [4, 36, 42, 12, 34]
It used postorder.
BinarySearchTree - size: $sizevalue height: $heightvalue
[4, 12, 34, 36, 42]
May I know did I need to change the tree and node?

I think you have a typo:
replace tree.insert(input); with:
for (int i = 0; i < data.length; i++) {
data[i] = sc.nextInt();
tree.insert(data[i]);
}
P.S. Preorder traversal will not give you expected output: sorted list. Tree Traversals (Inorder, Preorder and Postorder)
public final class BinarySearchTree {
private Node root;
private int size;
public void add(int val) {
root = add(root, new Node(val));
size++;
}
private static Node add(Node parent, Node node) {
if (parent == null)
return node;
if (node.val < parent.val)
parent.left = add(parent.left, node);
else
parent.right = add(parent.right, node);
return parent;
}
public boolean isEmpty() {
return size == 0;
}
public boolean find(int val) {
return dfsFind(root, val);
}
private static boolean dfsFind(Node node, int val) {
if (node == null)
return false;
if (node.val == val)
return true;
return dfsFind(node.left, val) || dfsFind(node.right, val);
}
public int[] getTraversals(Traversals traversals) {
int[] arr = new int[size];
traversals.print(root, arr, 0);
return arr;
}
public int size() {
return size;
}
public int height() {
return dfsHeight(root, 1);
}
private static int dfsHeight(Node node, int depth) {
if (node == null)
return depth - 1;
return Math.max(dfsHeight(node.left, depth + 1), dfsHeight(node.right, depth + 1));
}
public enum Traversals {
INORDER {
#Override
protected int print(Node node, int[] arr, int i) {
if (node != null) {
i = print(node.left, arr, i);
arr[i++] = node.val;
i = print(node.right, arr, i);
}
return i;
}
},
PREORDER {
#Override
int print(Node node, int[] arr, int i) {
if (node != null) {
arr[i++] = node.val;
i = print(node.left, arr, i);
i = print(node.right, arr, i);
}
return i;
}
},
POSTORDER {
#Override
int print(Node node, int[] arr, int i) {
if (node != null) {
i = print(node.left, arr, i);
i = print(node.right, arr, i);
arr[i++] = node.val;
}
return i;
}
};
abstract int print(Node node, int[] arr, int i);
}
private static final class Node {
private final int val;
private Node left;
private Node right;
public Node(int val) {
this.val = val;
left = right = null;
}
#Override
public String toString() {
return String.valueOf(val);
}
}
}
Demo:
Scanner scan = new Scanner(System.in);
System.out.print("Enter the number of the data: ");
int total = scan.nextInt();
int[] data = new int[total];
BinarySearchTree tree = new BinarySearchTree();
System.out.println("Enter the values: ");
for (int i = 0; i < data.length; i++) {
System.out.format("%d: ", i);
data[i] = scan.nextInt();
tree.add(data[i]);
}
System.out.print("Inserted: ");
System.out.println(Arrays.toString(data));
System.out.println("BinarySearchTree - size: " + tree.size() + " height: " + tree.height());
System.out.println("Inorder: " + Arrays.toString(tree.getTraversals(BinarySearchTree.Traversals.INORDER)));
System.out.println("Preorder: " + Arrays.toString(tree.getTraversals(BinarySearchTree.Traversals.PREORDER)));
System.out.println("Postorder: " + Arrays.toString(tree.getTraversals(BinarySearchTree.Traversals.POSTORDER)));
Output:
Enter the number of the data: 5
Enter the values:
0: 4
1: 36
2: 42
3: 12
4: 34
Inserted: [4, 36, 42, 12, 34]
BinarySearchTree - size: 5 height: 4
Inorder: [4, 12, 34, 36, 42]
Preorder: [4, 36, 12, 34, 42]
Postorder: [34, 12, 42, 36, 4]

to print the values of data either you need to iterate through the values using a for loop and print or you need to use Arrays class:
System.out.print(Arrays.toString(data) + " ");

Related

Jump search with Strings

i have been doing research on the jump search algorithm in an array. But i am confused on how you can use the search method with strings. Can anyone give me a link on where to look, or an example on here? Every example i have seen has been with numbers
public class JumpSearch
{
public static int jumpSearch(int[] arr, int x)
{
int n = arr.length;
int step = (int)Math.floor(Math.sqrt(n));
int prev = 0;
while (arr[Math.min(step, n)-1] < x)
{
prev = step;
step += (int)Math.floor(Math.sqrt(n));
if (prev >= n)
return -1;
}
while (arr[prev] < x)
{
prev++;
if (prev == Math.min(step, n))
return -1;
}
if (arr[prev] == x)
return prev;
return -1;
}
public static void main(String [ ] args)
{
int arr[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21,
34, 55, 89, 144, 233, 377, 610};
int x = 55;
// Find the index of 'x' using Jump Search
int index = jumpSearch(arr, x);
System.out.println("\nNumber " + x +
" is at index " + index);
}
}

Inserting array to BST in-order traverse

I want to traverse over a given tree using in-order traversal. inserting the sorted array into the BST (keeping it the same shape)
This is my go:
public static BinTreeNode<Integer> ARR_TO_BST(BinTreeNode<Integer> root, int[] arr, int ind){
if (root.GetLeft() != null)
ARR_TO_BST(root.GetLeft(), arr, ind);
root.SetInfo(arr[ind]);
ind+=1;
if (root.GetRight() != null)
ARR_TO_BST(root.GetRight(), arr, ind);
return root;
The problem is that if the array is arr = {10,20,30,40,50,60}
and the tree is:
The return output is a tree that if I do an in-order traversal over it is: 10 20 10 20 10 20 ... and not 10 20 30 40 50 60
I need the output to be the same shape of the picture but with the values of arr the algorithm is to traverse -in order on the tree : left subtree - vertex - right subtree
but instead of reading the values we insert the values from arr to root
I would appreciate help! thank you
You never change ind. After the first call to ARR_TO_BST, it remains what it was before the call. Make ARR_TO_BST return the number of elements it placed:
if (root.GetLeft() != null)
ind = ARR_TO_BST(root.GetLeft(), arr, ind);
root.SetInfo(arr[ind]);
if (root.GetLeft() != null)
ind = ARR_TO_BST(root.GetLeft(), arr, ind + 1);
return ind;
and you should be all right.
You can use accomplish by keep tracking the index of each element to add it back to the result array
static class BST {
private class Node {
private Integer key;
private Node left, right;
private int index;
public Node(Integer key, int index) {
this.key = key;
this.index = index;
}
}
private Node root;
private int size = 0;
public void put(int[] arr) {
if (size >= arr.length)
return;
root = put(root, arr[size], size);
size++;
put(arr);
}
private Node put(Node node, int key, int index) {
if (node == null)
return new Node(key, index);
int cmp = Integer.valueOf(key).compareTo(node.key);
if (cmp < 0)
node.left = put(node.left, key, index);
else if (cmp > 0)
node.right = put(node.right, key, index);
else
node.key = key;
return node;
}
public int size() {
return size;
}
public int[] keys() {
int[] result = new int[size];
get(root, result, 0);
return result;
}
public void get(Node node, int[] result, int i) {
if (i >= result.length || node == null)
return;
result[node.index] = node.key;
get(node.left, result, ++i);
get(node.right, result, ++i);
}
}
, main
public static void main(String[] args) {
BST bst = new BST();
bst.put(new int[] { 10, 20, 5, 40, 1, 60, -10, 0 });
for (int num : bst.keys()) {
System.out.print(num + " ");
}
}
, output
10 20 5 40 1 60

Quick Sort not sorting iterative solution

I currently have the below code for my quick sort. As you can see it is not producing the correct output. Any help will be greatly appreciated. I need the pivot to be the first item in the array. As you can also see i am measuring the time it takes to run, but please ignore that for the time being.
edit: to be specific it works correctly when i have a list in descending order and ascending order(already sorted), but when i try a random list it does not work.
Output:
QuickSort:
Quick Sort Took 181023 nanoseconds
Quick Sort Took 0 milliseconds
Sorted Quick Sort: 25, 12, 17, 13, 20, 7, 5, 16, 11, 26, 24, 18, 9, 4, 21, 1, 23, 27, 15, 19, 28, 14, 8, 22, 6, 3, 2, 10, 29, 40, 37, 32, 44, 38, 35, 41, 39, 31, 42, 30, 43, 36, 34, 33, 45, 46, 47, 48, 49, 50,
Code:
class QuickSort {
public static int Partition(int[] numbers, int left, int right){
//selects the first item at position [0] as the pivot
//left is given 0 when the method is called
int pivot = numbers[left];
while (true)
{
while (numbers[left] < pivot)
left++;
while (numbers[right] > pivot)
right--;
if (left < right)
{
int temp = numbers[right];
numbers[right] = numbers[left];
numbers[left] = temp;
}
else
{
return right;
}
}
}
//method to check for special cases
public static void QuickSort_Check(int[] numbers, int left, int right)
{
//special case of 2 items to be sorted
if(right == 1){
if(numbers[0] >= numbers[1]){
System.out.print("This is a special case of 2 inputs: ");
System.out.print(numbers[1] + ", " + numbers[0]);
System.exit(0);
}
else {
System.out.print("This is a special case of 2 inputs: ");
System.out.print(numbers[0] + ", " + numbers[1]);
System.exit(0);
}
System.exit(0);
}
//special case of 1 item to be sorted
else if (right == 0){
System.out.print("This is a special case of 1 input: ");
System.out.print(numbers[0]);
System.exit(0);
}
else {
QuickSort_Iterative(numbers, left, right);
}
}
public static class QuickPosInfo
{
public int left;
public int right;
};
public static QuickPosInfo spot = new QuickPosInfo();
public static void QuickSort_Iterative(int[] numbers, int left, int right)
{
if(left >= right)
return; // Invalid index range
LinkedList<QuickPosInfo> list = new LinkedList< QuickPosInfo>();
spot.left = left;
spot.right = right;
list.add(spot);
while(true)
{
if(list.size() == 0)
break;
left = list.get(0).left;
right = list.get(0).right;
list.remove(0);
int pivot = Partition(numbers, left, right);
if(pivot > 1)
{
spot.left = left;
spot.right = pivot - 1;
list.add(spot);
}
if(pivot + 1 < right)
{
spot.left = pivot + 1;
spot.right = right;
list.add(spot);
}
}
}
}
This partition method correctly sorted half the array, then did not sort the other half so I believe the problem is in your QuickSort_Iterative(); when the pivot equals 21 it just infinitely swaps 20 and 21.
private static int partition(int[] arr,int left,int right) {
int pivot = arr[right];
int small = left-1;
for(int k = left;k < right;k++)
{
if(arr[right] <= pivot)
{
small++;
swap(arr,right,small);
}
}
swap(arr,right,small+1);
System.out.println("Pivot= "+arr[small+1]);//prints out every sort
System.out.println(Arrays.toString(arr));
return small+1;
}
private static void swap(int[] arr, int k, int small) {//easy swap method
int temp;
temp = arr[k];
arr[k] = arr[small];
arr[small] = temp;
}
UPDATE
Here is the requested method. I believe that the problem with your original one is that you are not modifying that values of left and right properly as the array is sorted.
void QuickSort(int arr[], int left, int right)
{
// create auxiliary stack
int stack[] = new int[right-l+1];
// initialize top of stack
int top = -1;
// push initial values in the stack
stack[++top] = left;
stack[++top] = right;
// keep popping elements until stack is not empty
while (top >= 0)
{
// pop right and l
right = stack[top--];
left = stack[top--];
// set pivot element at it's proper position
int p = partition(arr, left, right);
// If there are elements on left side of pivot,
// then push left side to stack
if ( p-1 > left )
{
stack[ ++top ] = l;
stack[ ++top ] = p - 1;
}
// If there are elements on right side of pivot,
// then push right side to stack
if ( p+1 < right )
{
stack[ ++top ] = p + 1;
stack[ ++top ] = right;
}
}
}
I don't know that will help you out or not you can also try the below code for same.
public class Demo {
private int array[];
private int length;
public void sort(int[] inputArr) {
if (inputArr == null || inputArr.length == 0) {
return;
}
this.array = inputArr;
length = inputArr.length;
quickSort(0, length - 1);
}
private void quickSort(int lowerIndex, int higherIndex) {
int i = lowerIndex;
int j = higherIndex;
int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
while (i <= j) {
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
if (i <= j) {
exchangeNumbers(i, j);
i++;
j--;
}
}
if (lowerIndex < j)
quickSort(lowerIndex, j);
if (i < higherIndex)
quickSort(i, higherIndex);
}
private void exchangeNumbers(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String a[]){
Demo sorter = new Demo();
int[] input = {8,693,29,3,2,8,29,82,4,26,2,62,82,6,52,9,42,6,52,66,2,8};
sorter.sort(input);
for(int i:input){
System.out.print(i);
System.out.print(" ");
}
}
}

I'm using a min-heap here, but i'm doing it wrong. I'm trying to print out some sheep in breadth order while also being sorted lightest to heaviest

My heap is suppposed to print out in breadth order and sort the sheep from lightest to heaviest (min-heap). My test file should add 15 sheep and remove at least 5. I havent attempted the remove part yet because i'm getting an array index out of bounds error. Any help is appreciated.
Here are my classes:
public class Sheep {
private double weight;
private String name;
public Sheep()
{
weight = 0.0;
name = "null";
}
public Sheep(double aWeight, String aName)
{
this.weight = aWeight;
this.name = aName;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//may not be necessary...
#Override
public String toString() {
return "Sheep [weight=" + weight + ", name=" + name + "]";
}
//this may not be necessary...
public int compareTo(Sheep sheep)
{
if (this.weight>sheep.weight)
return 1;
else if(this.weight<sheep.weight)
return -1;
else
return 0;
}
}
//****************************************
public class SheepHeapMain {
private Sheep[]heap;
private static int size;
private static final int FIRST=1; //possibly needed, how do you do this
public SheepHeapMain()
{
heap = (Sheep[])(new Comparable[100]);
size = 0;
}
public SheepHeapMain(int aSize)
{
heap = new Sheep[aSize];
}
public void addSheep(Sheep val)
{
if(size >= heap.length)
{
System.out.println("Max size of heap has been reached");
return;
}
heap[size] = val;
climbUp();
size++;
}
public void climbUp()
{
int index = this.size;
while(index>0 &&//It has a parent
heap[index/2].compareTo(heap[index])<0)//And the value of the child is greater than the parent
{
//SWAP
Sheep temp = heap[index/2];
heap[index/2] = heap[index];
heap[index] = temp;
index = index/2;
}
}
public Sheep peek()
{
if(heap == null)
return null;
return heap[0];
}
public Sheep removeSheep()
{
Sheep returnVal = peek();
heap[0] = heap[size-1]; //index Out of bonunds error
heap[size-1] = null;
size--;
climbDown();
return returnVal;
}
public void climbDown()
{
int index = 0;
while(index*2+1 < size)//While there is a left child
{
//Find smallest child
int bigIndex = index*2+1;
if(index*2+2 < size &&
heap[index*2+1].compareTo(heap[index*2+2])>0) //Right was bigger than left so change it
{
bigIndex = index*2+2;
}
if(heap[index].compareTo(heap[bigIndex])<0)//If current index is greater than smaller index
{
//SWAP
Sheep temp = heap[index];
heap[index] = heap[bigIndex];
heap[bigIndex] = temp;
}
else
{
break;//We're done!
}
index = bigIndex;//Update the index to continue
}
}
public void sheepRollCall()
{
for(Sheep thing : heap)
{
if(thing == null)
break;
System.out.println(thing.toString());
System.out.println("");
}
}
public static void sheepHeapSort(SheepHeapMain heap)
{
SheepHeapMain tempheap = heap;
for(int i=size;i>0;i++)
{
System.out.println(tempheap.removeSheep()+" ");
System.out.println();
}
}
}
//****************************************************************
public class SheepHeapTester {
public static void main(String[] args) {
final int heapSize = 15;
SheepHeapMain heap = new SheepHeapMain(heapSize);
heap.addSheep(new Sheep(55,"Jimmy"));
heap.addSheep(new Sheep(43,"Ricky"));
heap.addSheep(new Sheep(77,"Larry"));
heap.addSheep(new Sheep(12,"Suzie Q"));
heap.addSheep(new Sheep(91,"Curly"));
heap.addSheep(new Sheep(85,"Bubba"));
heap.addSheep(new Sheep(189,"MEGA SHEEP"));
heap.addSheep(new Sheep(46,"Bo Peep"));
heap.addSheep(new Sheep(27,"Queenie"));
heap.addSheep(new Sheep(19,"Fluffy"));
System.out.println("current thing is");
heap.sheepRollCall();
System.out.println();
System.out.println("Sorted Sheepies :)");
SheepHeapMain.sheepHeapSort(heap);
}
}
You're getting the ArrayIndexOutOfBoundsException because you are trying to reference index of -1 in your heap array.
I added a line to print size and heap.length:
public Sheep removeSheep()
{
System.out.println("removeSheep size: " + size + " array size: " + heap.length);
Sheep returnVal = peek();
heap[0] = heap[size-1]; //index Out of bonunds error
heap[size-1] = null;
size--;
climbDown();
return returnVal;
}
And here is the output:
Sorted Sheepies :)
removeSheep size: 10 array size: 15
Sheep [weight=189.0, name=MEGA SHEEP]
removeSheep size: 9 array size: 15
Sheep [weight=77.0, name=Larry]
removeSheep size: 8 array size: 15
Sheep [weight=27.0, name=Queenie]
removeSheep size: 7 array size: 15
Sheep [weight=46.0, name=Bo Peep]
removeSheep size: 6 array size: 15
Sheep [weight=19.0, name=Fluffy]
removeSheep size: 5 array size: 15
Sheep [weight=55.0, name=Jimmy]
removeSheep size: 4 array size: 15
Sheep [weight=43.0, name=Ricky]
removeSheep size: 3 array size: 15
Sheep [weight=85.0, name=Bubba]
removeSheep size: 2 array size: 15
Sheep [weight=91.0, name=Curly]
removeSheep size: 1 array size: 15
Sheep [weight=12.0, name=Suzie Q]
removeSheep size: 0 array size: 15
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at SheepHeapMain.removeSheep(SheepHeapMain.java:55)
at SheepHeapMain.sheepHeapSort(SheepHeapMain.java:107)
at SheepHeapTester.main(SheepHeapTester.java:24)
As for fixing your code, here is a standard heap-sort algorithm that sorts in descending order using a min-heap that you can use as a reference:
public class HeapSort {
private static int getLeft(int index) {
return index * 2 + 1;
}
private static int getRight(int index) {
return index * 2 + 2;
}
private static void exchange (int[] arr, int first, int second) {
int temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
private static void minHeapify (int[] arr, int size, int index) {
int left = getLeft(index);
int right = getRight(index);
int minIndex = index;
if (left < size && arr[left] < arr[minIndex])
minIndex = left;
if (right < size && arr[right] < arr[minIndex])
minIndex = right;
if (index != minIndex) {
exchange(arr, index, minIndex);
minHeapify (arr, size, minIndex);
}
}
private static void buildMinHeap (int[] arr) {
int size = arr.length;
for (int i = ((size-1) / 2); i >= 0; i --) {
// Do max-heapify on the i.
minHeapify (arr, size, i);
}
}
public static void heapSort(int[] arr) {
int size = arr.length;
buildMinHeap(arr);
for (int i = size - 1; i >= 0; i--) {
exchange (arr, 0, i);
minHeapify (arr, i, 0);
showArray(arr);
}
}
public static void showArray (int[] arr) {
int size = arr.length;
for (int i = 0; i < size; i++)
System.out.print(String.format("%-4d", arr[i]));
System.out.println();
}
public static void main (String[] args) {
int[] arr = {53, 42, 86, 11, 27, -5, 89, 0};
heapSort(arr);
showArray(arr);
}
}

How to convert sorted array to a BST?

I'm struggling to get my desired output below. This is what I have done so far, and I think I'm close to being done.
import java.util.Scanner;
public class sortedArrayBST {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
try {
if (n <= 0) {
input.close();
}
int m = input.nextInt();
if (m <= 0) {
input.close();
}
int[] s = new int[n];
int[] w = new int[m];
for (int i = 0; i < n; i++) {
s[i] = input.nextInt();
}
for (int i = 0; i < m; i++) {
w[i] = input.nextInt();
}
} catch (IllegalStateException e) {
}
}
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode parent;
TreeNode(int x) {
val = x;
}
}
public static TreeNode sortedArrayToBST(int[] num) {
if (num == null || num.length == 0)
return null;
int start = 0, end = num.length - 1;
TreeNode root = buildTree(num, start, end);
return root;
}
public static TreeNode buildTree(int[] num, int start, int end) {
if (start > end) {
return null;
}
int mid = start + (end - start) / 2;
TreeNode node = new TreeNode(num[mid]);
node.left = buildTree(num, start, mid - 1);
node.right = buildTree(num, mid + 1, end);
return node;
}
}
I have to take user input such as:
4 // denotes number of elements in array S, variable n.
2 // number of elements in array W, variable m.
0 // 0, 25, 33, 77 are in S.
25
33
77
19 // 19 and 40 are in W.
40
Those numbers represent the sentence positions, so the ends of each sentence.
The output is
2 // 2 words of interest found, this value is always the same as W above
1 25 // start of the sentence with 1st occurrence of word of interest (end of previous sentence + 1) and end of the sentence (aka ".")
34 77 // so the previous sentence before this ended at position 33, so the next sentence started at 34, and it ends at 77.
IDK how to get this using a sorted array to a BST.
If I understand you correctly, I think what you're looking for, is a way to traverse the bst you constructed to print the output in the given format.
If that is the case, you can do an inorder traversal of the tree to achieve that.(Although, having a sorted array, constructing a bst out of it and then printing the bst in a sorted order is kind of an overkill don't you think?)
static boolean flag = false;
public static void inorderTraverse(TreeNode root){
if(root == null) return;
inorderTraverse(root.left);
if(flag){
System.out.print(root.val);
System.out.print("\n");
flag = false;
}
else{
flag = true;
System.out.print(root.val + 1 + " ");
}
inorderTraverse(root.right);
}

Categories

Resources