Insertion Sort & Binary Search insertion sort - java

I am having trouble implementing the insertionSort() method.
import java.util.Random;
import java.util.Arrays;
public class Lab6 {
static final int SIZE = 100;
static int[] values = new int[SIZE];
static void initValues() {
Random rand = new Random();
for(int i =0; i< SIZE;i++) {
values[i] = rand.nextInt(100);// limit to 100
}
}
static boolean isSorted() {
boolean sorted = true;
for(int i=0;i<SIZE-1;i++) {
if(values[i] > values[i+1]){
sorted = false;
}
}
return sorted;
}
static void swap(int index1, int index2) {
int temp = values[index1];
values[index1] = values[index2];
values[index2] = temp;
}
static void insertElement(int endIndex) {
// FILL IN CODE HERE
boolean finished = false;
int current = endIndex;
boolean moretoSearch = true;
while (moretoSearch && !finished){
if (values[current] < values[current-1]){
swap(current, current-1);
current--;
}
else
finished = true;
}
}
I am also not sure if this method "insertElementBinary(int endIndex)" is correctly implemented;
static void insertElementBinary(int endIndex) {
//FILL IN CODE HERE FOR BINARY SEARCH INSERTIONSORT
boolean finished = false;
int current = endIndex;
boolean moretoSearch = true;
while (moretoSearch && !finished){
if (values[current] < values[current-1]){
swap(current, current-1);
current--;
moretoSearch = (current != endIndex);
}
else
finished = true;
}
}
This is where my major problems are:
static void insertionSort() {
//FILL IN CODE HERE
for (int i =0; i < SIZE; i++){
insertElement(i);
insertElementBinary(i);
}
}
The rest of this is good:
public static void main(String[] args) {
Lab6.initValues(); // generate the random array
System.out.println(Arrays.toString(values));
System.out.println(isSorted());
insertionSort();
System.out.println(Arrays.toString(values));
System.out.println(isSorted());
}
}

You're very close to having it correct.
In your insertElement(int endIndex) method, you need to make sure your current > 0, shown below, or else you're going to have an array out of bounds error.
static void insertElement(int endIndex) {
boolean finished = false;
int current = endIndex;
boolean moretoSearch = true;
while (moretoSearch && !finished && current > 0){
if (values[current] < values[current-1]){
swap(current, current-1);
current--;
}
else
finished = true;
}
}
The same fix applies to your insertElementBinary(int endIndex) method. You can test both by commenting out insertElement(i) or insertElementBinary(i) in the insertionSort() method. Both will work fine now.

Related

BubbleDown function(min heap) not working

I have generated a minheap to this file but I think something I have missed but I can't identify what are the things I have missed. I have missed something on --private void bubbleDown() { }-- section but I can't find what are the things missed by me.
private int default_size = 100; // how big the heap should be
private T[] array;
private int size;
public Heap() {
#SuppressWarnings("unchecked")
T[] tmp = (T[]) (new Comparable[default_size]);
array = tmp;
size = 0;
}
boolean isRoot(int index) { return (index == 0); }
int leftChild(int index) { return 2 * index + 1; }
int parent(int index) { return (index - 1) / 2; }
int rightChild(int index) { return 2 * index + 2; }
T myParent(int index) { return array[parent(index)]; }
T myLeftChild(int index) { return array[leftChild(index)]; }
T myRightChild(int index) { return array[rightChild(index)]; }
boolean hasLeftChild(int i) { return leftChild(i) < size-1; }
boolean hasRightChild(int i){ return rightChild(i) < size-1; }
private void swap(int a, int b) {
T tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
public boolean isEmpty() { return (size == 0); }
/* adding heap */
public void add(T value) {
if(size == default_size) throw new IllegalStateException("Full array");
array[size++] = value;
bubbleUp();
}
public void bubbleUp() {
if(size == 0) throw new IllegalStateException("Shape error");
int index = size - 1;
while(!isRoot(index)) {
if(myParent(index).compareTo(array[index]) <= 0) break;
/* else part */
swap(parent(index), index);
index = parent(index);
}
}
/* removing */
public T remove() {
if(isEmpty()) return null;
T res = array[0]; /* root */
array[0] = array[size-1];
size --;
bubbleDown();
return res;
}
// i think this section having wrong something
private void bubbleDown() {
int parent = 0;
int leftChild = 2*parent + 1;
int rightChild = 2*parent + 2;
int choice = compareAndPick(leftChild, rightChild);
while (choice != -1)
{
swap(choice, parent);
parent = choice;
choice = compareAndPick(2*choice+1, 2*choice+2);
}
}
private int compareAndPick(int leftChild, int rightChild)
{
if (leftChild >= default_size || array[leftChild] == null) return -1;
if (array[leftChild].compareTo(array[rightChild]) <= 0 || (array[rightChild] == null))
return leftChild;
return rightChild;
}
public void show() {
for(int i=0; i<size; i++)
System.out.print(array[i] + " ");
System.out.println("=======");
}
public static void main(String [] args) {
Heap<Integer> heap = new Heap<Integer>();
for(int i=0; i<10; i++) {
heap.add((Integer)(int)(Math.random() * 100));
heap.show();
}
System.out.println("You should see sorted numbers");
while(!heap.isEmpty()) {
System.out.print(heap.remove());
System.out.print(" ");
heap.show();
}
System.out.println();
}
}
this code used generics and min heap functions.. i need to identify what is the wrong thing did by me on bubbleDown() section
Explanation
The bubbleDown() method is not a different way to insert a node and move it to it's correct position in the Heap. When bubbleDown() is called it's job is to Heapify the Binary Tree from any state. So your attempt to write the method just by changing the condition from the bubbleUp() method isn't gonna help you.
Extra
Here is a video that can give you the idea of how bubbleDown is supposed to work.

Does not find specific number in array

I am trying to write a program that creates an array and fill it with int numbers(first method). In the end, it is supposed to see if a specific number is given in the array(second method). The problem is that the program does not run my if loops. I do not know why.
The variable x is the number the program is looking for in the array and pos the position of the number in the array
public class Program {
static int [] numbers= new int[100];
public static void main(String [] args) {
PrintWriter out = new PrintWriter(System.out);
arrayConstruction();
test(out);
out.flush();
}
public static void arrayConstruction() {
int x = 0;
for (int i = 0; i < numbers.length; i++) {
numbers[i] = x;
x++;
}
}
public static void test(PrintWriter out) {
int x = 17;
int pos = 0;
if(pos != numbers.length) {
if(numbers[pos] == x) {
out.println("The number was found!");
out.flush();
}
pos++;
}
else if(pos == numbers.length) {
out.println("The number does not exist!");
out.flush();
}
}
}
You forgot to add a loop to the test method, so it checks the first array's item only. E.g. you can use while loop.
public static void test(PrintWriter out) {
int x = 17;
int pos = 0;
while (true) {
if (pos != numbers.length) {
if (numbers[pos] == x) {
out.println("The number was found!");
return;
}
pos++;
} else if (pos == numbers.length) {
out.println("The number does not exist!");
return;
}
}
}
I think you should redesign your code by splitting different activities with separate methods. It makes your code clear to understand.
public class Main {
public static void main(String[] args) {
int[] arr = createArray(100);
System.out.println(isNumberExist(arr, 17) ? "The number was found!"
: "The number does not exist!");
}
public static int[] createArray(int total) {
int[] arr = new int[total];
Random random = new Random();
for (int i = 0; i < arr.length; i++)
arr[i] = random.nextInt(arr.length);
return arr;
}
public static boolean isNumberExist(int[] arr, int x) {
for (int i = 0; i < arr.length; i++)
if (arr[i] == x)
return true;
return false;
}
}
You should add a while loop to your test method, like this:
public static void test(PrintWriter out) {
int x = 17;
int pos = 0;
while(pos < numbers.length) {
if(numbers[pos] == x) {
out.println("The number was found!");
out.flush();
break;
}
pos++;
}
if(pos == numbers.length) {
out.println("The number does not exist!");
out.flush();
}
}
In your method, the if statement will only be executed once.

HackerRank Java 1D Array (Part 2)

I am trying to solve the following question HackerRank Java 1D Array
I have come up with the following backtracking approach.
import java.util.Scanner;
public class Solution {
static int arr[];
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int T = sc.nextInt();
for (int j= 0; j < T; j++) {
int n = sc.nextInt();
arr = new int[n];
int m = sc.nextInt();
for (int k = 0; k< n; k++) {
arr[k]= sc.nextInt();
}
if(canReach(0,arr.length,m))
System.out.println("YES");
else
System.out.println("NO");
}
}
public static boolean canReach(int src,int dest,int m)
{
if(src>=(dest-1)||(src+m)>=dest)
return true;
if(isValidDest(src+1)&&canReach(src+1, dest, m))
return true;
if(isValidDest(src-1)&&canReach(src-1, dest, m))
return true;
if(isValidDest(src+m)&&canReach(src+m, dest, m))
return true;
return false;
}
private static boolean isValidDest(int dest) {
if(((dest>=0&&dest<arr.length)&&(arr[dest]==0)))
return true;
return false;
}
}
But I am getting a stack-overflow error for the following test case 0 0 1 1 1 0.
Could anyone help me out on how to avoid this stack-overflow error, while keeping intact the backtracking approach.
Modified code (solution)
import java.util.Scanner;
public class Solution {
static int arr[];
static boolean isDestVisited[];
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int T = sc.nextInt();
for (int j= 0; j < T; j++) {
int n = sc.nextInt();
arr = new int[n];
isDestVisited = new boolean[n];
int m = sc.nextInt();
for (int k = 0; k< n; k++) {
arr[k]= sc.nextInt();
}
if(canReach(0,arr.length,m))
System.out.println("YES");
else
System.out.println("NO");
}
}
public static boolean canReach(int src,int dest,int m)
{
if(src>=(dest-1)||(src+m)>=dest)
return true;
if(isDestVisited[src]==true)
return false;
isDestVisited[src]=true;
if(isValidDest(src+1)&&canReach(src+1, dest, m))
return true;
if(isValidDest(src-1)&&canReach(src-1, dest, m))
return true;
if(isValidDest(src+m)&&canReach(src+m, dest, m))
return true;
isDestVisited[src]=false;
return false;
}
private static boolean isValidDest(int dest) {
if(((dest>=0&&dest<arr.length)&&(arr[dest]==0)))
return true;
return false;
}
}
In recursive algo you must to avoid processing of same state twice
if (src >= dest)
return true;
if (thisPositionAlreadyTested[src])
return false;
thisPositionAlreadyTested[src] = true;
if ( ...
or you can reuse arr[] content for same purpose if you can modify it

My code is not printing all the elements of the queue. What is the error?

This is my Queue class. I have implemented it using arrays.
public class QueueUsingArray {
private int data[];
private int firstElementIndex;
private int nextElementIndex;
private int size;
public QueueUsingArray() {
data = new int[10];
firstElementIndex = -1;
nextElementIndex = 0;
size = 0;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size() == 0;
}
private void checkEmpty() throws QueueEmptyException {
if (size == 0) {
QueueEmptyException e = new QueueEmptyException();
throw e;
}
}
public int front() throws QueueEmptyException {
checkEmpty();
return data[firstElementIndex];
}
public int dequeue() throws QueueEmptyException {
checkEmpty();
int output = data[firstElementIndex];
size--;
data[firstElementIndex] = 0;
firstElementIndex = (firstElementIndex + 1) % data.length;
if (size == 0) {
firstElementIndex = -1;
nextElementIndex = 0;
size = 0;
}
return output;
}
public void enqueue(int element) {
if (size == data.length) {
int[] temp = data;
data = new int[data.length * 2];
int k = 0;
for (int i = firstElementIndex; i < temp.length; i++) {
data[k] = temp[i];
k++;
}
for (int i = 0; i < firstElementIndex; i++) {
data[k] = temp[i];
k++;
}
firstElementIndex = 0;
nextElementIndex = temp.length;
}
if (size == 0) {
firstElementIndex = 0;
}
data[nextElementIndex] = element;
size++;
nextElementIndex = (nextElementIndex + 1) % data.length;
}
}
Here is my QueueUse class.
public class QueueUse {
public static void main(String[] args) throws QueueEmptyException {
QueueUsingArray q=new QueueUsingArray();
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
q.enqueue(40);
q.enqueue(50);
q.enqueue(60);
q.enqueue(70);
q.enqueue(80);
q.enqueue(90);
q.enqueue(100);
q.enqueue(110);
q.enqueue(120);
q.enqueue(130);
q.enqueue(140);
q.enqueue(150);
q.enqueue(160);
q.enqueue(170);
q.enqueue(180);
q.enqueue(190);
q.enqueue(200);
q.enqueue(210);
q.enqueue(220);
q.enqueue(230);
q.enqueue(240);
q.enqueue(250);
q.enqueue(260);
q.enqueue(270);
q.enqueue(280);
q.enqueue(290);
q.enqueue(300);
System.out.println("All elements");
for(int i=0;i<q.size();i++){
try {
System.out.println(q.dequeue());
} catch (QueueEmptyException e) {
System.out.println("Sorry");
}
}
}
}
My output is not complete. Output is not showing all the elements in my queue. What is the error. Output is only showing until 140 and not beyond that.
Your print method does not work because you decrement the size every time you invoke your dequeue() method in the for loop. If you are going to use a for loop you should be using a fixed size. Basically in this statement ( i < q.size() ) as i grows size decreases. If i = 0 and size = 4 the first loop i would be 1 and size would be 3. Your never going to get to the 0th or 1st element in your queue because by the next loop your already at i = 2 and size = 3.
first you should add a getter for the queue items
public int getElementAt(int index){
return data[index];
}
then you can call the method in the for loop for every index in data
int length = q.size();
for(int i = 0; i < length; i++){
System.out.println(q.getElementAt(i));
}
If it is not mandatory to do an array implementation, I would suggest using the Vector class because it has a better API for a queue. I would also suggest slowly tracing your program every time you have issues and to start with smaller test data sets to make tracing a easier.
public class Queue {
private Vector<String> data ;
Queue(){
data = new Vector();
}
public void enqueue(String item){
data.add(item);
}
public void dequeue(){
data.remove(0);
}
public void printQueueItems(){
int length = data.size();
for(int i = 0; i < length; i++){
System.out.println(data.get(i));
}
}
public static void main(String[] args) {
Queue myQ = new Queue();
myQ.enqueue("hello");
myQ.enqueue("world");
myQ.enqueue("!");
myQ.printQueueItems();
}
}

boolean allLess(int[] one,int[] two) method

so I am trying to make this method that takes in two int Arrays and returns true if each element in the first array is less than the element at the same index in the second array if the arrays are of different lengths then it will compare up to the length of the shorter array. this is what i have so far but i keep failing two j unit tests and cant figure out what is causing it. Thank you for any help in advance.
here are the two junit tests i am failing
#Test
public void testSecondLessFirstLonger() {
int[] one = { 5, 5, 5 };
int[] two = { 4 };
boolean actual = Program1.allLess( one, two );
assertFalse( "Incorrect result",actual );
}
#Test
public void testSecondLessSecondLonger() {
int[] one = { 2 };
int[] two = { 1, 0 };
boolean actual = Program1.allLess( one, two );
assertFalse( "Incorrect result",actual );
}
import java.util.Arrays;
here is the code i have so far
public class Program1 {
public static void main(String[] args)
{
int[] one = { 2 };
int[] two = { 1, 0 };
System.out.println(allLess(one, two));
}
public static boolean allLess(int[] one,int[] two)
{
if (one.length != two.length)
{
int len = 0;
if(one.length <= two.length)
{
len = one.length;
}
if(two.length < one.length)
{
len = two.length;
}
boolean[] boo = new boolean[len];
for(int i = 0; i < len; i++)
{
if(one[i] < two[i])
{
boo[i] = true;
}
else
{
boo[i] = false;
}
}
if(Arrays.asList(boo).contains(false))
{
return false;
}
else
{
return true;
}
}
for (int i = 0; i < one.length; i++)
{
if (one[i] >= two[i])
{
return false;
}
}
return true;
}
}
Perhaps you could try something like this:
public static boolean allLess(final int[] array1, final int[] array2){
for(int i = 0; i < Math.min(array1.length, array2.length); i++)
if(array1[i] >= array2[i])
return false;
return true;
}
//this way works too. did you get program 3 done yet? Its giving me issues
import java.lang.Math.*;
public class Program1 {
public static boolean allLess(int[] one, int[] two) {
if (one == null || two == null) {
return false;
}
for (int i = 0; i < Math.min(one.length, two.length); i++) {
if (two[i] <= one[i]) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println(" ");
}
}

Categories

Resources