Java : Selection Sort Logic - java

I am printing Sorted Array elements using Selection Sort. But I am getting my input array elements as output in same sequence without sorting.
public class SelectionSort {
public static void main(String[] args) {
int[] arr= {1,9,3,0,7};
int n=arr.length;
for(int i=0; i<n-1; i++)
{
int minimumIndex = i;
for(int j=i; j<n; j++)
{
if(arr[j]<arr[minimumIndex])
{
minimumIndex=j;
}
}
int temp=arr[i];
arr[i]=arr[minimumIndex];
arr[i]=temp;
}
for(int e: arr)
{
System.out.print(e+" ");
}
}
}
Expected o/p : 0 1 3 7 9
Actual o/p: 1 9 3 0 7

In Your method code, the actual problem is swapping elements,
the Sequence needs to be like this as below,
int temp=arr[minimumIndex];
arr[minimumIndex]=arr[i];
arr[i] =temp;
instead of
int temp=arr[i];
arr[i]=arr[minimumIndex];
arr[i]=temp;

There are two issues I see. One is the way you are swapping the items. You need to replace the item where you found the minimum index. Also, your J index should start one after your I index. You can assume that the one before it is the smallest as you are looping through. I have changed a few pieces of the code and tested it and it works fine for me.
for (int i = 0; i < arr.length - 1; i++)
{
int minimumIndex = i;
for (int j = i + 1; j < arr.length; j++)
{
if (arr[j] < arr[minimumIndex])
{
minimumIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minimumIndex];
arr[minimumIndex] = temp;
}

Related

Is this a selection sort or a bubble sort?

Is this a selection sort? I think it is Bubble Sort because I'm using (dot)compareTo. I look at different sources on the internet so I can make one. Here is the codes.
import java.util.Arrays;
public class SelectionSort {
public static void main(String args[]) {
String[] row = {"apple", "orange", "banana", "grapes", "mango", "avocado"};
int min = row.length;
for(int m = 0; m < min-1; m++) {
for (int n = m+1; n < row.length; n++) {
if(row[m].compareTo(row[n]) > 0){
String bar = row[m];
row[m] = row[n];
row[n] = bar;
}
}
}
System.out.println("Expected Outcome: " + Arrays.toString(row));
}
}
this is not selection sort
I selection sort in each iteration you find minimum value and put it to the proper location. See this picture
A simple implementation show here:
https://www.javatpoint.com/selection-sort-in-java
public class SelectionSortExample {
public static void selectionSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++)
{
int index = i;
for (int j = i + 1; j < arr.length; j++){
if (arr[j] < arr[index]){
index = j;//searching for lowest index
}
}
int smallerNumber = arr[index];
arr[index] = arr[i];
arr[i] = smallerNumber;
}
}
public static void main(String a[]){
int[] arr1 = {9,14,3,2,43,11,58,22};
System.out.println("Before Selection Sort");
for(int i:arr1){
System.out.print(i+" ");
}
System.out.println();
selectionSort(arr1);//sorting array using selection sort
System.out.println("After Selection Sort");
for(int i:arr1){
System.out.print(i+" ");
}
}
}
It is not Selection Sort (Milad already answered this), but it is also not Bubble Sort.
The way you can tell that it is not bubble sort, is because bubble sort compares pairs of items that are next to each-other (ex: compares items at index 0-1, 1-2, 2-3... and swaps if necessary). In your code, when m=0, the inner loop will compare item at index 0 with all the other items in the array.
Bubble Sort in Java:
public void sort( int[] array) {
boolean isSorted;
for (var i = 0; i < array.length; i++) {
isSorted = true;
for (var j = 1; j < array.length - i ; j++)
if (array[j] < array[j - 1]) {
swap(array, j, j - 1);
isSorted = false;
}
if (isSorted)
return;
}
}
private void swap(int[] array, int index1, int index2) {
var temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}

Why does my sorting algorithm fails after the 3rd iteration of the for loop?

/*
This is the prompt:
starts with an unsorted array a
output: sorted array a.
Find the smallest element in the array a[1: n], call it a[j].
Swap it with a[0], if it is smaller than a[0].
Repeat this process with index 1, 2, ... until the who array is sorted.
*/
public class assing2 {
public static void main(String args[])
{
//array of ints
int[] A = new int[] {33, 20, 8, 11, 5};
int min_id = 0;
int temp_i = 0;
//int temp_max = 0;
for (int i = 0; i < A.length; i++)
{
min_id = i;
temp_i = A[i];
for (int j = 1; j < A.length; j++)
{
if (A[min_id] > A[j])
{
min_id = j;
}
}
A[i] = A[min_id];
A[min_id] = temp_i;
}
System.out.println("Sorted array");
for ( int i = 0; i < A.length; i++)
{
System.out.println(A[i]);
}
}
}
This is the output
Sorted array
5
20
11
33
8
When I run it in the debugger i can see that the first 2 iterations of the first for loop looks like its working but after that it unsorted what was sorted.
Whats is wrong with my logic?
for (int j = 1; j < A.length; j++)
is wrong. You should check only the elements after i, since the elements before i are sorted by the previous iterations. So it should be
for(int j = i+1; j < A.length; j++)
Also in the first loop, you dont need to do anything about the last element. You can change the stop condition to i<A.length-1

ArrayOutOfBoundsException in java

I have following code in Java.
public class TestArray
{
public static void main(String s[])
{
int arr[]={23,12,1,4,1,4,23,6};
int temp=arr[0];
for(int i=0;i<arr.length;i++)
{
for(int j=0;j<arr.length;j++)
{
if(arr[i]>arr[j+1])
{
temp=arr[j+1];
arr[j+1]=arr[i];
arr[i]=temp;
}
if(arr[i]==arr[j+1])
{
arr[j+1]=arr[j+2];
}
}
}
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}
But this code is throwing
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at com.test.java.TestArray.main(TestArray.java:16)
Could anyone help me with this ?
An attempt to index arr[j + 1] or arr[j + 2] will fail when j is arr.length - 1.
Should you run your indexes to one less than you currently do? Also, that final flourish where you index j + 2 looks unnecessary.
As a style point, keep the scope of temp as tight as possible. You only need it when you swap two array elements.
Looks like you are trying to sort the array in descending order. You can try this:
public class TestArray
{
public static void main(String s[])
{
int arr[]={23,12,1,4,1,4,23,6};
int n = arr.length;
int temp = 0;
for(int i=0; i < n; i++){
for(int j=1; j < (n-i); j++){
if(arr[j-1] < arr[j]){
//swap elements
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}
You can understand the code.
If you are wondering how you got exception, refer answer by Bathsheba
Modify your code into
for(int i=0;i<arr.length-1;i++) {
for(int j=i;j<arr.length-1;j++) {
if(arr[i]>arr[j+1]) {
temp=arr[j+1];
arr[j+1]=arr[i];
arr[i]=temp;
}
if(arr[i]==arr[j+1]) {
arr[j+1]=arr[j+2];
}
}
}
In your loop, value of j will be from 0 to 7. And you are trying to access the j+1'th position of array. So when j has value 7 you are accessing a[8] and it is not within the bounds of the array size. An array of size 8 will have index values from 0 to 7.

No duplicates in an array [duplicate]

This question already has answers here:
How to get unique values from array
(13 answers)
Closed 8 years ago.
void RemoveDups(){
int f=0;
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
{
arr[k]=arr[k+1];
}
nelems--;
}
if(i==(nelems+1)){
f++;
i=f+1; //increment again
}
}
}
This is the logic i have written to remove duplicate elements from an array ,but this is not working at all ?what changes i should make to make it work? or you people have better logic for doing the same considering time complexity.and i don't want to use built-in methods to achieve this.
int end = input.length;
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (input[i] == input[j]) {
int shiftLeft = j;
for (int k = j + 1; k < end; k++, shiftLeft++) {
input[shiftLeft] = input[k];
}
end--;
j--;
}
}
}
I think you can use Set Collection
copy all the values to an HashSet and then using Iterator access the Values
Set<Integer> hashset= new HashSet<Integer>();
You have two options, C# has the Distinct() Linq expression that will do this for you (Missed the Java tag), however if you need to remove items, have you thought about sorting the list first, then comparing the current item to the previous item and if they're the same, remove them. It would mean your diplicate detection is only ever running through the array once.
If you're worried about sort you could easily implement an efficient bubble sort or somthing to that effect
You never decrease i after You compared for examlpe arr[0] to arr[5], You never will test arr[1] == arr[2]
You need to start a new loop (i) after You've incremented f.
try
for(int f=0;f<nelems-1;f++)
{
for(int i=f+1;i<nelems;i++)
{
...
}
}
with this nested for loop you can compare every two element of the array.
a good start is to eliminate duplicate elements without shrinking the array which is done lastly:
public class run2 extends Thread {
public static void main(String[] args) {
int arr[] = { 1, 2, 2, 3, 5, 6, 5, 5, 6, 7 };
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] == -1)
j++;
if (arr[i] == arr[j])
arr[j] = -1;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == -1) {
for (int j = i; j < arr.length; j++) {
if (arr[j] != -1) {
arr[i] = arr[j];
arr[j] = -1;
break;
}
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
Adapt this code :
public static int[] removeDuplicates(int[] numbersWithDuplicates) {
// Sorting array to bring duplicates together
Arrays.sort(numbersWithDuplicates);
int[] result = new int[numbersWithDuplicates.length];
int previous = numbersWithDuplicates[0];
result[0] = previous;
for (int i = 1; i < numbersWithDuplicates.length; i++) {
int ch = numbersWithDuplicates[i];
if (previous != ch) {
result[i] = ch;
}
previous = ch;
}
return result;
}
As far as I understood from your code,you are comparing each value starting from index 0 to the rest of the element and when you see the element which is located at index f your are trying to shift the entire array and decrementing the size of array(nelems).Look at line no. 11
if(i==(nelems+1)){
f++;
i=f+1;
The problem is when i is set to f+1,i will again be incremented in the for loop for the next iteration.So basically i starts comparing from f+2.And also you are comparing i with (nelems+1) considering the case when nelems decremented but you are not considering the case when i reaches the end without decreasing nelems in that case i will never be equale to (nelems+1).Now considering your logic you could do 2 things.
1.Here is your working code.
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i+1;k<nelems;k++)
{
arr[k-1]=arr[k];
}
if(i==(nelems-1)){
f++;
i=f;
}
nelems--;
}
if(i==(nelems-1)){//end of the loop
f++;
i=f; //increment again
}
}
2.You could use an outer for loop alternatively that will increment the f value once the inner for is completed.
void RemoveDups(){
for(int f=0;f<nelems;++f){
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
arr[k]=arr[k+1];
nelems--;
}
}
}
}
Now your problem is solved but the time complexity of your code will be(O(N^3)).
Now instead of shifting the entire array at line 4,you could just swap the arr[f] with last element.
if(arr[f]==arr[i]){
swap(arr[f],arr[nelems-1]);
nelems--;
}
it will reduce the time complexity from O(N^3) to O(N^2).
Now I'll suggest you my method
1.just sort the array.It will be done in O(NlogN).
2.now using one for loop you can get what do you wanted.
void RemoveDups(){
int k=0,i;
for(i=1;i<nelems;++i){
while(arr[i]==arr[i-1])
++i;
arr[k++]=arr[i-1];
}
arr[k++]=arr[i-1];
}
Now basically you got an array of size k,which contains non repeated element in sorted order and the time complexity of my solution is O(NlogN).

Array Index Out of Bounds Exception in Java in case of Insertion Sort

class Insertionsort
{
int A[] = {5,2,4,6,1,3};
void insertionSort()
{
for(int j=2;j<A.length;j++)
{
int key = A[j];
int i = j-1;
while(i>0 && A[i]>key)
{
A[i+1]=A[i];
i=i-1;
}
A[i+1]=key;
}
for(int j = 0;j<=A.length;j++)
{
System.out.println(A[j]);
}
}
public static void main(String args[])
{
Insertionsort is = new Insertionsort();
is.insertionSort();
}
}
Problem is:
The Output of this is 5 1 2 3 4 6 instead of 1 2 3 4 5 6.
What to do?
This is causing the error:
for(int j = 0;j<=A.length;j++)
System.out.println(A[j]);
Max index of an array is length - 1 so change it to:
for(int j = 0;j<A.length;j++)
System.out.println(A[j]);
Better yet, why not use the enhanced for? That way you don't make this kind of mistake:
for(int a : A)
System.out.println(a);
Back to your algorithm:
Starting from j=2 you leave out your first element so change it to j=1.
Also your inner loop should go until i>=0 else you also leave out the 0th element (array index is 0-based):
for (int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i = i - 1;
}
A[i + 1] = key;
}
This will print out 1 2 3 4 5 6 (in new lines since println() is used).
If you want to sort an Array, you just need to use Sort() from Arrays class.
Arrays.sort(yourArray);
for(int j = 0;j<=A.length;j++)
change to j<A.length to make your OutOfBounds Exception go away.
also, your other loops have wrong start/end conditions
for(int j=2;j<A.length;j++) should start at j=1 and while(i>0 && A[i]>key) should have i>=0 or the first element in the array will be skipped in your sort (the 5).
In your sorting loop you initialize j = 2 and then get an number from the array with int key = A[j]; so the first number in the array you try to sort is index 2. Since the first element in an array has the index 0, you are leaving out 5 and 2 when sorting. Change the loop to
for(int j = 0; j < A.length(); j++){
int key = A[j];
int i = j-1;
....
class Insertionsort
{
int A[] = {5,2,4,6,1,3};
void insertionSort()
{
for(int j=1;j<A.length;j++)
{
int key = A[j];
int i = j-1;
while(i>=0 && A[i]>key)
{
A[i+1]=A[i];
i=i-1;
}
A[i+1]=key;
}
for(int j = 0;j<A.length;j++)
{
System.out.print(A[j] + " ");
}
}
public static void main(String args[])
{
Insertionsort is = new Insertionsort();
is.insertionSort();
}
}

Categories

Resources