Bubble sort swap method clarification - java

Ive been following a course that goes over bubble sort but one part of the swap method implementation has been bothering me. The part that doesnt make sense to me and hoping someone can clarify has to do with the comparison regarding the index.
public static void main(String[] args) {
int[] intArray = {20, 35, -15, 7, 55, 1, -22};
//start at index 6 which is -22 value; as long as the length of the array is more than 0; decrement down to the first index
for (int lastUnsortedIndex = intArray.length -1; lastUnsortedIndex > 0; lastUnsortedIndex -- ){
//i=0; as long as i is less than length of intArray -1, so 6; i++
for(int i =0; i< lastUnsortedIndex; i++){
//if value at index i is more than value at index i+1
if(intArray[i] > intArray[i +1]){
//swap their positions
swap(intArray, i , i+1);
}
}
}
for(int num : intArray){
System.out.println(num);
}
}
//for swapping
public static void swap (int[] array , int i , int j){
System.out.println("i= "+i);
System.out.println("j= "+j);
if(i == j){ // if they are the same then just return
return;
}
int temp = array[i];// need the temporary variable to hold value at position i because
//... we are going to swap array[i] with j, but still need to retain the value so we can assign it to array[j]
array[i] = array[j];
array[j] = temp;
}
As you can see if(i == j){return;} seems to only be comparing the index if im not mistaken. Why even bother doing this check? Doesnt seem like i will ever equal i+1, unless I'm missing something here?

There's no reason to do the check. It's also pointless to pass i+1 to swap. Just pass i, and replace j with i+1 everywhere. Don't worry about checking for equality. Remove the print statements if you care about speed.

Related

Why am I not able to return the index of the array in the output?

I am not able to return the index of the elements as an output
// Using Two pointers Approach
class Solution {
public int[] twoSum(int[] nums, int target){
// Initilizing the index i and j
int i = 0, j = nums.length-1;
// Using while loop
while (i<j){
if((nums[i] + nums[j] > target)){
j--;
}else if((nums[i] + nums[j] < target)){
i++;
}else{
// Trying to return the index of the elements but getting elements in the output
return new int[] {nums[i], nums[j]};
}
} // while loop ends here
return new int[] {};
}
}
I'm not sure what I am doing wrong.
Actually i and j are the index numbers of that array, so you must have seen the output as empty array just because in your other test case the while loop ends when i = 1 and j = 1 and the condition for the loop is i < j so the next loop won't happen. So to return the values of index which is {1, 1} according to yor other test case you have to return the new int [] {i , j}; after the end of while loop. It's not necessary to add a return statement inside the while loop.

Java: Increment operation not working inside if block

I am writing a small code for bubble sort using Java as below
package raja.programming.bubblesort;
public class Main {
public static void main(String[] args) {
// write your code here
//int[] intArray = {5, -10, 22, 43, 1, 17};
int[] intArray = { 20, 35, -15, 7, 55, 1, -22 };
for ( int unsortedArrayIndex = intArray.length -1 ; unsortedArrayIndex > 0 ; unsortedArrayIndex--){
for ( int index = 0 ; index < unsortedArrayIndex ; index++){
System.out.println("index " + intArray[index] + " index+1 : " + intArray[index+1] );
if ( intArray[index] > intArray[index+1]) {
swap(intArray, index, index+1);
}
}
}
for (int num: intArray) {
System.out.println(num);
}
}
public static void swap( int[] array, int i, int j) {
if ( i == j) {
return ;
}
System.out.println("swap index " + array[i] + " index+1 : " + array[j] );
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
In the line if ( intArray[index] > intArray[index+1]) { I am passing as index+1 then only my code working, if I pass i++ or ++i its not working.
What is the reason behind this behaviour, please help me understand?
Thank you.
When you use index + 1 your code compares the element at the position index and the one at the position index +1 and the loop adds 1 at the end of the instuctions inside the loop
But if you use ++i or i++ your code will do the same thing but the index you used will jump by 2 the incrementation of the for loop and the incrementation you did.
it will not work if you do i++ beacuse this will increment i and return the previous value of i before incrementing so it's like you compare the element to itself
But if you use ++i it will increment the value of i and return the value incremented. But in both ways, in one loop, you increment i twice. If you really want to use either of those you need to remove the for loop and use a while loop and use ++i
i think the reason is. if u are using an index i for example and u increment it inside the loop, u will jump the next iteration. i++ is equals to i = i+1, but i+1 is not equals to i=i+1
You are iterating using index, when you are referring the position in an array using index + 1then the value ofindex` variable is not changed.
But if you use index++ or ++index, then you are incrementing the value of the index variable by 1 in that iteration and you will be skipping one index. Because of the same reason, the output array you are getting is unsorted in this case.

Returning the K biggest element from an array. (JAVA)

public static Word[] simpleSelect(Word[] array, int k){
k= array.length;
for(int i = 0; i< k-1; i++){
for(int j = 0; j<k-i-1; j++){
if(array[j].compareTo(array[j+1]) < 0){
swap(array,j, j+1);
}
}
}
return array;
}
I created this above code to return the K biggest elements from an array through a bubble sort. I am suppose to make this method O(nk).
I have wrote this code and figured that the returned array doesn't print an array with k size. Instead, it just prints the original array with the same length, just bubble sorted.
For example, if I my original array is {1,19, 7 ,26 ,9 ,85} and my k value is 2, I want it to return {85,26}.
Instead, currently this code is returning {85,26,19,9,7,1} no matter what the k value is.
I would like to know what i am doing wrong here and also would like to know if I am coding right in O(nk) times.
k is re-assigned on line 2: k = array.length; it's the reason why the method behaves regardless of the value of k.
As for complexity bubble sort has an average complexity of O(n^2), it must be adapted to meet your O(nk) requirements.
Assume we have the following array of numbers
static int[] arr = {456, 12 , 998, 546, 12, 987, 6456, 66, 9789};
We are going to construct the array of k largest numbers by iteratively finding the largest number of the array and then marking that number so that it does not get picked again.
This is the method that will find the k largest elements:
private static int[] kLargest(int[] arr, int k){
int[] klargest = new int[k];
for(int i=0;i<k;i++){
klargest[i] = findAndMarkLargest(arr);
}
return klargest;
}
And this is the method that find the single largest element, and then marks it (by setting the elements to Integer.MIN_VALUE)
private static int findAndMarkLargest(int[] arr){
int largest = Integer.MIN_VALUE;
for(int i=0;i<arr.length;i++){
if(arr[i] > largest){
largest = arr[i];
}
}
for(int i=0;i<arr.length;i++){
if(arr[i] == largest){
arr[i] = Integer.MIN_VALUE;
}
}
return largest;
}
The main method (that simply calls the kLargest method) looks like this:
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
System.out.println(Arrays.toString(kLargest(arr, 3)));
}
And outputs:
[9789, 6456, 998]
Each call to findAndMarkLargest takes 2*n operations (since it runs over the array twice).
The method findAndMarkLargest is called k times by 'kLargest'. So, in terms of big O notation, this is O(2kn) which is equivalent to O(nk)

Array Index out of Bound exception in a program for reverse of an array

Here is the code to reverse an array
import java.util.*;
class middle {
public static void main(String args[]){
int a[]=new int[]{2,3,65,4,7,8,9};
int c[]=new int[a.length-1];
int k=0;
for(int i=a.length;i>0;i++){
c[k]=a[i];
k++;
}
System.out.println("Reverse of an array");
for(int i=0;i<c.length;i++)
System.out.print(c[i]+" ");
}
}
while running gives Array index out of bound exception:7
where the code is going wrong?
a.length is out of bound for a
for(int i=a.length;i>0;i++)
{
c[k]=a[i];
k++;
}
then,
int c[]=new int[a.length-1];
you need same length array for, not length - 1 for reverse array
To loop through the array backwards, you need to change all three conditions in your loop, like so:
for(int i=a.length-1;i>=0;i--)
{
c[k]=a[i];
k++;
}
Let's take this apart:
int i=a.length-1;
You must begin at a.length-1, as arrays use 0-based indexing and a.length is out of bounds.
i>=0;
You need to iterate until i>=0, as i>0 will miss one element of your array.
i--
You need to decrement i, as the loop will always access out of bounds indexes/never terminate otherwise.
P.S. As #Jigar mentioned, you need to initialize c as int c[]=new int[a.length];.
you did mistake here , you need to mention the length of array a.length not a.length-1 for c and the values in for loop conditions should have like for(int i=a.length-1;i>=0;i--) i should be decremented. : modified code is here:
int a[]=new int[]{2,3,65,4,7,8,9};
int c[]=new int[a.length];
int k=0;
for(int i=a.length-1;i>=0;i--)
{
c[k]=a[i];
k++;
}

Add element into array java

Here's what the layout is
index num
0 [10]
1 [20]
2 [30]
(Add 35 here)
3 [40] Move elements down
4 [50]
5 [60]
6 [70]
then my method is this
public static void method(int[] num, int index, int addnum)
{
}
How can i add 35 in there?
Tried this:
public static void method(int[] num, int index, int addnum)
{
int index = 10;
for(int k = num.length k>3; k++)
{
Num[k]=num[k++]
}
Num[3] = 35;
As this is something you should accomplish yourself, I will only provide the method to implement it, not the code:
If you would set the number at position index, you would overwrite the value that was there previously. So what you need to do is move every element one position towards the end of the array starting from index: num[x] becomes num[x+1], etc.
You will find out that you need to do this in reverse order, otherwise you will fill your array with the value in num[index].
During this process you will need to decide what to do with the last entry of the array (num[num.length - 1]):
You could just overwrite it, discarding the value
You could return it from your function
You could throw an exception if it is non-zero
You could create a new array that is 1 entry larger than the current array instead to keep all values
etc.
After this, you have duplicated num[index]: the value is present in num[index+1], too, as you have moved it away.
Now it is possible to write the new value at the desired position without overriding an existing value.
EDIT
You have several errors in your code:
You increment k, you need to decrement it (k--, not k++)
You modify k again in your loop body: it is updated twice in each cycle
If you start with k = num.length, you will try to write at num[num.length + 1], which is not possible
Very crudely, you want to do something like this:
public static void(int[] num, int index, int addnum)
{
// initialize new array with size of current array plus room for new element
int[] newArray = new int[num.length + 1];
// loop until we reach point of insertion of new element
// copy the value from the same position in old array over to
// same position in new array
for(int i = 0; i < index; i++)
{
newArray[i] = num[i];
}
i = i + 1; // move to position to insert new value
newArray[i] = addnum; // insert the value
// loop until you reach the length of the old array
while(i < num.length)
{
newArray[i] = num[i-1];
}
// finally copy last value over
newArray[i + 1] = num[i];
}
You need to
allocate a new array with room for one new element.
int[] newArray = new int[oldArray.length + 1];
Copy over all elements and leave room for the one to insert.
for (int i = 0; i < newArray.length - 1; i++)
newArray[i < insertIndex ? i : i + 1] = oldArray[i];
Insert 35 in the empty spot.
newArray[insertIndex] = numberToInsert;
Note that it's not possible to do in a method like this:
public static void method(int[] num, int index, int addnum)
^^^^
since you can't change the length of num.
You need to allocate a new array, which means that need to return the new array:
public static int[] method(int[] num, int index, int addnum)
^^^^^
and then call the method like this:
myArr = method(myArr, 3, 35);
Since this very closely resembles homework what you need to realize is that you cannot dynamically increase the size of an array. So in your function:
public static void(int[] num, int index, int addnum)
{
int[] temp = new int[num.length *2];
for(int i = 0; i < index; i++)
copy num[i] into temp[i]
insert addnum into temp[index]
fill temp with remaining num values
}
That pseudocode above should get you started.
What you're looking for is an insertion sort.
It's classwork, so it's up to you to figure out the proper code.
Well, you can't unless there is "extra space" in your array, and then you can shift all elements [starting from index] one element to the right, and add 35 [num] to the relevant place.
[what actually happen is that the last element is discarded out].
However - a better solution will probably be to use an ArrayList, and use the method myArrayList.add(index,element)
How about this?
public class test {
public static void main(String[] arg) throws IOException
{
int[] myarray={1,2,3,5,6};//4 is missing we are going to add 4
int[] temp_myarray=myarray;//take a temp array
myarray=addElement(myarray,0);//increase length of myarray and add any value(I take 0) to the end
for(int i=0;i<myarray.length;i++)
{ if(i==3) //becaues I want to add the value 4 in 4th place
myarray[i]=4;
else if(i>3)
myarray[i]=temp_myarray[i-1];
else
myarray[i]=temp_myarray[i];
}
for(int i=0;i<myarray.length;i++)
System.out.print(myarray[i]);//Print new array
}
static int[] addElement(int[] arr, int elem) {
arr = Arrays.copyOf(arr, arr.length + 1);
arr[arr.length - 1] = elem;
return arr;
}
}

Categories

Resources