We have to sort an Array with random numbers. For this, we need to use this part of code ( HeapSort )
import java.util.ArrayList;
public class HeapSort<E extends Comparable<E>> {
public ArrayList<E> h;
public int SIZE;
public int n;
public HeapSort(int s){
SIZE=s;
n=1;
h=new ArrayList<>(SIZE);
for(int i=0;i<SIZE;i++)
h.add(null);
}
public void Insert(E e){
h.set(n,e);
n++;
// swapping up
if(n!=2){ // more than 1 element
int s=n-1; // last added element
int p=s/2; // its parent
while(s!=1 && LT(s,p)){
swap(p,s);
s=p;
p=p/2;
}
}
}
public boolean Empty(){
return n==1;
}
public E Lesser(){
return h.get(1);
}
public void Delete(){
n--;
h.set(1,h.get(n)); // last element to the root
h.set(n,null);
// swapping down
int ip=1;
int ils=2;
int irs=3;
while(ConditionSwapDown(ip,ils,irs)){
if(Exists(ils) && Exists(irs)){
// two sons
if(LT(ils,ip) || LT(irs,ip)){
// at least one child is lesser than the parent -> swap
if(LT(ils,irs)){
swap(ip,ils); // swapping down left
ip=ils;
ils=ip*2;
irs=ils+1;
}
else{
swap(ip,irs); // swapping down right
ip=irs;
ils=ip*2;
irs=ils+1;
}
}
}
else
// only left son
if(Exists(ils) && !Exists(irs)){
if(LT(ils,ip)){ // left son is lesser than the parent
swap(ip,ils);
ip=ils;
ils=ip*2;
irs=ils+1;
}
}
// else no children and end of swapping down
}
}
public boolean ConditionSwapDown(int p,int l,int r){
// (has 2 children and (parent>left or parent>right)) or
// (has 1 children and parent>left)
return (((Exists(l) && Exists(r)) && (LT(l,p) || LT(r,p)))) ||
(Exists(l) && !Exists(r) && LT(l,p));
}
public boolean Exists(int p){
if(p>=SIZE)
return false;
return h.get(p)!=null;
}
public void swap(int a,int b){
E c=h.get(a);
h.set(a,h.get(b));
h.set(b,c);
}
public boolean LT(int a,int b){ // h[a]<h[b]
return h.get(a).compareTo(h.get(b))<0;
}
#Override
public String toString(){
String r="";
for(int i=1;i<n;i++)
r+=h.get(i)+" ";
return r;
}
public String Print(){
return PrintR(1,"");
}
public String PrintR(int i,String p){
String r=p+h.get(i)+"\n";
if(h.get(i*2)!=null || h.get(i*2+1)!=null){
if(h.get(i*2)!=null)
r+=PrintR(i*2,p+" ");
else
r+=p+" -\n";
if(h.get(i*2+1)!=null)
r+=PrintR(i*2+1,p+" ");
else
r+=p+" -\n";
}
return r;
}
How do we "connect" the two codes? or use our array with HeapSort? For the Array we have done this:
public class P3 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("Quina llargada tindrĂ la taula? ");
int n = reader.nextInt(); //n=llargada taula
int[] taula = new int[n];
int fi = 100*n;
Random rand = new Random();
//int al = rand.nextInt(fi) + 0;
for (int i = 0; i < taula.length; i++)
taula[i] = rand.nextInt(fi);
System.out.println(Arrays.toString(taula)); }}
Everything is in the HeapSort class, waiting for you to use it:
int[] taula = {4, 2, 8, 1, 2, 3};
System.out.println(Arrays.toString(taula));
// 'heapSort' variable will store ordered list
HeapSort<Integer> heapSort = new HeapSort<>(taula.length+1);
for (Integer i : taula)
heapSort.Insert(i);
System.out.println(heapSort);
Related
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.
I was learning about quick find and made a very basic implementation in java but my union function was not working properly when I initially implemented it. I made some changes and it started working but I'm not sure whats causing the problem in the first iteration of my function. I can see that for some reason the parent of P is changing even though I'm not making any changes to the argument p but I don't know why. Sorry if this is a stupid question I'm just lost here.
First attempt
public class QuickFindUF {
private int[] id;
public QuickFindUF(int N){
id = new int[N];
for (int i = 0;i<N;i++){
id[i] = i;
}
}
public boolean connected(int p, int q){
if (id[p] == id[q]){
return true;
}
return false;
}
public int find(int x){
return id[x];
}
public void union(int p, int q){
if (connected(p,q)) {
System.out.println(p+" and "+q + " are already connected");
return;
}
for (int i =0; i < id.length;i++){
if (id[i] == find(p)){
System.out.println("p's parent is " + find(p) + " list item is "+id[i]);
id[i] =find(q);
}
}
}
public void print(){
System.out.print("[");
for (int i =0; i < id.length; i++){
System.out.print(id[i]);
System.out.print(", ");
}
System.out.println("]");
}
public static void main(String args[]){
QuickFindUF qfobj = new QuickFindUF(10);
qfobj.print();
qfobj.union(3,5);
qfobj.print();
qfobj.union(3,8);
qfobj.print();
}
}
second (working) attempt
public class QuickFindUF {
private int[] id;
public QuickFindUF(int N){
id = new int[N];
for (int i = 0;i<N;i++){
id[i] = i;
}
}
public boolean connected(int p, int q){
if (id[p] == id[q]){
return true;
}
return false;
}
public int find(int x){
return id[x];
}
public void union(int p, int q){
if (connected(p,q)) {
System.out.println(p+" and "+q + " are already connected");
return;
}
int pid = find(p);
int qid = find(q);
for (int i =0; i < id.length;i++){
if (id[i] == pid){
System.out.println("p's parent is " + find(p) + " list item is "+id[i]);
id[i] =qid;
}
}
}
public void print(){
System.out.print("[");
for (int i =0; i < id.length; i++){
System.out.print(id[i]);
System.out.print(", ");
}
System.out.println("]");
}
public static void main(String args[]){
QuickFindUF qfobj = new QuickFindUF(10);
qfobj.print();
qfobj.union(3,5);
qfobj.print();
qfobj.union(3,8);
qfobj.print();
}
}
The purpose of this project is:
Create a class called IntegerSet that implements Comparable interface to be used in simple set applications. Each object of class IntegerSet can hold positive integers in the range 0 through 255 and most common set operations are available. A set must be represented internally as an int array of ones and zeros (or a boolean array). Array element a[ i ] is 1 if integer i is in the set and array element a[ j ] is 0 if integer j is not in the set.
and then add some member method to modify it.
I am not familiar with "implements Comparable interface," but here is what I got so far. The driver cannot test it, it shows "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 256"
Can someone help me find out what the problem is? thanks!
import java.util.Arrays;
public class IntegerSet implements Comparable
{
private int L = 256;
private int[] a = new int[L];
public IntegerSet()
{
Arrays.fill(a, 0);
}
public IntegerSet(int n)
{
a[n] = 1;
}
public IntegerSet(int[] n)
{
a = n;
}
public IntegerSet union(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i]==1 || other.a[i] ==1)
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet intersection(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i]==1 && other.a[i] ==1)
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet difference(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i] != other.a[i])
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet insertElement(int k)
{
a[k] = 1;
IntegerSet temp = new IntegerSet(a);
return temp;
}
public IntegerSet removeElement(int k)
{
a[k] = 0;
IntegerSet temp = new IntegerSet(a);
return temp;
}
public boolean isElement(int k)
{
return(a[k] == 1);
}
public String toString()
{
String str = "";
for(int i = 0; i < L; i++)
{
if(a[i] == 1)
str += (i + ", ");
}
return "{" + str + "}";
}
public IntegerSet copy()
{
IntegerSet temp = new IntegerSet(a);
return temp;
}
public boolean subset(IntegerSet other)
{
boolean sub = true;
int i = 0;
while(sub)
{
if(this.a[i] == 1)
{
if(other.a[i] == 1)
sub = true;
else
sub = false;
}
i++;
}
return sub;
}
public boolean superset(IntegerSet other)
{
boolean sup = true;
int i = 0;
while(sup)
{
if(other.a[i] == 1)
{
if(this.a[i] == 1)
sup = true;
else
sup = false;
}
i++;
}
return sup;
}
public void addAll()
{
Arrays.fill(a, 1);
}
public void removeAll()
{
Arrays.fill(a, 0);
}
public int compareTo(Object other)
{
// TODO Auto-generated method stub
return 0;
}
}
and the driver:
public class IntegerSetDriver
{
public static void main(String[] args)
{
IntegerSet s1, s2, s3, s4, s5;
s1 = new IntegerSet(); // s1 is an empty set, {}
s2 = new IntegerSet(5); // s2 is a set with one element, {5}
s1.insertElement(1); // s1 is now {1}
s3 = s1.copy(); // s3 is now {1}
s4 = s1.union(s2); // s4 is now {1, 5} and s1 is still {1}
s5 = s4.insertElement(8).removeElement(5); // s4 is now {1, 8} // s5 references s4
int result = s3.compareTo(s4); // result is -1 (or < 0)
boolean yes = s3.subset(s4); // yes should be true
s5.removeAll(); // s4 and s5 both reference same empty set, {}
s1.removeElement(500); // invalid element so ignore, s1 is still {1}
}
}
You should check your bounds before adding/removing from your int[] a (i.e. 500 is not a valid index).
Also, look at your constructor IntegerSet(input[] n), you cannot just directly "assign" it like that. You need to parse the array and update your local a[] properly.
"n" ranges from 0-255 for values, whereas "a" should only be {1,0}.
A few other things need fixing too.
I need to modify a class to create a dynamic array stack.
My code at this point looks something like this:
public class DynamicArrayStack<E> implements Stack<E> {
private E[] elems; //used to store the elements
public static final int defaultIncrement = 25;
private final int increment;
private int top;
#SuppressWarnings( "unchecked" )
public DynamicArrayStack( int increment ) {
this.increment = increment;
elems = (E[]) new Object[ increment ];
top = 0;
}
/**
* Constructor with no parameter that will initialize
* the stack to have an array whose size is the value
* of increment and memorise that value as the value
* of increment.
*/
public void ArraySize() { }
public boolean isEmpty() {
return top == 0;
}
public E peek() {
return elems[ top-1 ];
}
public E pop() {
// save the top element
E saved = elems[ --top ];
// scrub the memory, then decrements top
elems[ top ] = null;
return saved;
}
public void push( E elem ) {
// stores the element at position top, then increments top
elems[ top++ ] = elem;
}
public String toString() {
StringBuffer b;
b = new StringBuffer( "DynamicArrayStack: {" );
for ( int i=top-1; i>=0; i-- ) {
if ( i!=top-1 ) {
b.append( "," );
}
b.append( elems[ i ] );
}
b.append( "}" );
return b.toString();
}
}
How do I edit the first constructor to set increment as the initial size of the stack and that same value to be used when increasing or decreasing the size of the array. My method for doing this seems way too simple. Parameter must be > 0 and a fixed number of cells are added or removed when the size of the array changes.
The second constructor should set the stack to have an array whose size is the value of increment. I keep getting errors here because I can't figure out how to do that because I thought that was already set in the first constructor. Also the size of the array as the value of increment.
Also how do I make this class capable of changing the capacity of the stack and into which method should I place that code?
Here is the simple java code to implement it:
1)Stack based:
public class DynamicArrayStack {
public static void main(String[] args) {
DynamicStack dstack=new DynamicStack(2);
System.out.println("--Pushing--");
dstack.push(1);
dstack.push(2);
dstack.display();
dstack.push(3);
dstack.push(2);
dstack.push(5);
dstack.display();
System.out.println("--Popping--");
dstack.pop();
dstack.pop();
dstack.pop();
dstack.display();
}
}
class DynamicStack {
private int top;
private int capacity;
private int[] array;
public DynamicStack(int cap) {
capacity = cap;
array = new int[capacity];
top = -1;
}
public void push(int data) {
if (isFull()){
expandArray(); //if array is full then increase its capacity
}
array[++top] = data; //insert the data
}
public void expandArray() {
int curr_size = top + 1;
int[] new_array = new int[curr_size * 2];
for(int i=0;i<curr_size;i++){
new_array[i] = array[i];
}
array = new_array; //refer to the new array
capacity = new_array.length;
}
public boolean isFull() {
if (capacity == top+1)
return true;
else
return false;
}
public int pop() {
if (isEmpty()) {
System.out.println("Stack is empty");
return -1;
} else {
reduceSize(); //function to check if size can be reduced
return array[top--];
}
}
public void reduceSize() {
int curr_length = top+1;
if (curr_length < capacity / 2) {
int[] new_array = new int[capacity / 2];
System.arraycopy(array, 0, new_array, 0, new_array.length);
array = new_array;
capacity = new_array.length;
}
}
public boolean isEmpty() {
if (top == -1)
return true;
else
return false;
}
public void display() {
for (int i = 0; i <= top; i++) {
System.out.print(array[i] + "=>");
}
System.out.println();
System.out.println("ARRAY SIZE:" + array.length);
}
}
OUTPUT:
--Pushing--
1=>2=>
ARRAY SIZE:2
1=>2=>3=>2=>5=>
ARRAY SIZE:8
--Popping--
1=>2=>
ARRAY SIZE:4
2)Link List based:
public class LinkListStack {
public static void main(String[] args) {
StackList stack = new StackList();
System.out.println("--Pushing--");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.push(6);
stack.display();
System.out.println("--Popping--");
stack.pop();
stack.pop();
stack.display();
}
}
class Node {
private int data;
private Node next;
public Node(int d) {
data = d;
next = null;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
class StackList {
private Node top;
private int length;
public StackList() {
length = 0;
top = null;
}
public void push(int data) {
Node temp = new Node(data);
if (top == null) {
top = temp;
} else {
temp.setNext(top);
top = temp;
}
length++;
}
public int pop() {
Node temp=top;
int data = top.getData();
top = top.getNext();
temp=null;
length--;
return data;
}
public void display() {
Node temp = top;
if (isEmpty()) {
System.out.println("Stack is empty");
} else {
while (temp != null) {
System.out.print(temp.getData() + "=>");
temp = temp.getNext();
}
}
System.out.println();
}
public boolean isEmpty() {
return (top == null);
}
}
OUTPUT:
--Pushing--
6=>5=>4=>3=>2=>1=>
--Popping--
4=>3=>2=>1=>
Default constructor
Your default constructor could simply call your other constructor with a default increment value. For example:
public DynamicArrayStack() {
this(defaultIncrement);
}
Expanding the array
The correct place to expand the array is within the push method. When attempting to add a new element you can check if the array is large enough, and if not create a new larger array. For example you could do the following:
#Override
public E push(final E elem) {
// Check if we need to expand the array
if (elems.length - 1 == top) {
#SuppressWarnings("unchecked")
final E[] newElems = (E[]) new Object[elems.length + increment];
System.arraycopy(elems, 0, newElems, 0, elems.length);
elems = newElems;
}
// stores the element at position top, then increments top
elems[top++] = elem;
return elem;
}
If you want to shrink the array the sensible place to do this would be in the pop() method. You might want to consider only reducing the length when (top + (increment*2))<elems.length to avoid repeatedly copying arrays when you're on the boundary.
My goal is to traverse a maze using a stack, but I am unable to get very far.
I have a 2D array of Room objects and I always start at position 1,1. I believe I have everything set up correctly. However, I keep getting a NullPointerException whenever I try to access the data stored in my array.
Any assistance that will point me in the right direction would be appreciated.
Here is my room class:
import java.awt.Point;
public class Room {
private Room up;
private Room down;
private Room left;
private Room right;
private char value;
private boolean blocked;
private boolean visited = false;
private Point p;
public void setCord(int row, int column) {
p = new Point(row, column);
}
public void setUp(Room [][] r, int row, int column) {
up = r[row][column];
}
public void setDown(Room[][] r, int row, int column) {
down = r[row][column];
}
public void setRight(Room[][] r, int row, int column) {
right = r[row][column];
}
public void setLeft(Room[][] r, int row, int column) {
left = r[row][column];
}
public void setValue(char c) {
value = c;
}
public void setVisited(boolean b) {
visited = b;
}
public void setBlocked(boolean b) {
blocked = b;
}
public Point getCord() {
return p;
}
public Room getUp() {
return up;
}
public Room getDown() {
return down;
}
public Room getRight() {
return right;
}
public Room getLeft() {
return left;
}
public char getValue() {
return value;
}
public boolean getVisited() {
return visited;
}
public boolean getBlocked() {
return blocked;
}
}
Here is my maze class:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.*;
import javax.swing.JOptionPane;
public class Maze {
String inFile, // Name of file to be used as input
outFile, // Name of file to output completed maze to
line; // Current line being read by scanner
char [][] mazeContent;
Room [][] rooms;// Holds the values that create maze
Room [] theStack;
Room current = new Room();
ArrayList<Room> al;
int rows, columns;
int tos = 0;
char [][] mazeC;
public static void main(String []args) throws Exception {
Maze m = new Maze();
}
public Maze() throws FileNotFoundException {
// Prompts user for the name of the file they wish to use as the input file.
inFile = JOptionPane.showInputDialog(null, "Please enter the name of the file you wish to read, including " +
"the file path:");
//if(inFile.equals("")) inFile = "C:\Java\JavaFiles\maze1.txt;
// Prompts user to enter the name they wish to save the file under.
outFile = JOptionPane.showInputDialog(null, "Please enter the filename you wish to save the data to:");
// Creates a scanner object to read in the input file.
Scanner readFile = new Scanner(new FileReader(inFile));
PrintWriter output = new PrintWriter(outFile);
rows = readFile.nextInt();
columns = readFile.nextInt();
readFile.nextLine();
theStack = new Room[1000];
mazeContent = new char [rows][columns];
rooms = new Room [rows][columns];
theStack = new Room[1000];
for(int i = 0; i < rows; i++) {
line = readFile.nextLine();
for(int j = 0; j< line.length(); j++) {
mazeContent[i][j] = line.charAt(j);
}
}
createRooms();
findPath();
}
private void findPath() {
Room start = rooms[1][1];
push(start);
while(!isEmpty()) {
current = pop();
//System.out.println("The value is " + current.getValue());
if(current.getValue() == '$') {
System.out.println("Success");
}
else if(current.getBlocked() != true && current.getVisited() != true) {
current.setVisited(true);
push(current.getRight());
push(current.getLeft());
push(current.getUp());
push(current.getDown());
}
}
}
public void createRooms() {
for(int i = 1; i < rows - 1; i++) {
for(int j = 1; j < columns -1; j++) {
Room r = new Room();
r.setCord(i,j);
r.setValue(mazeContent[i][j]);
r.setUp(rooms, i-1, j);
r.setDown(rooms, i+1, j);
r.setRight(rooms, i, j+1);
r.setLeft(rooms, i, j-1);
if(mazeContent[i][j] == '*')
r.setBlocked(true);
else
r.setBlocked(false);
rooms[i][j] = r;
}
}
}
private Room pop() {
return theStack[--tos];
}
private boolean isEmpty() {
// TODO Auto-generated method stub
return tos == 0;
}
private void push(Room item) {
if (isFull()) {
System.out.println("The stack is full!");
}
else
theStack[tos++] = item;
}
private boolean isFull() {
return tos == theStack.length-1;
}
}
The most likely root cause of your NullPointerException is that you have not (fully) initialized something. Perhaps a field of one of your objects. Perhaps an element of on of your arrays. When you then try to use this uninitialized field or array element, you are actually trying to perform an operation on a null reference ... and that causes the exception.
If the exception is being thrown by
if(current.getValue() == '$')
then that means that current is null. That means that you "popped" a null from your stack. On first sight, the implementations of your stack operations look OK, so my guess is that somewhere you have pushed a null.
My suggestion is to add a test in the push method that throws an exception if you attempt to push null. (Or try and track this down using a debugger.) Then continue working backwards to figure out where the null came from.