Selection Sort wrong output - java

I am trying to understand the SelectionSort for arrays.
If I understand it correctly, it compares the element[minimum] with the next elements element[i] and swaps positions if element[i] < element[minimum]. Then it repeats this with element[i + 1] until the list is sorted.
Now when I try it with the following code, I get an incorrect sort and can't figure out what I'm doing wrong.
public static void SelectionSort1(int[] list){
for (int i = 0; i < (list.length - 1); i++){
int min = i;
for (int j = i + 1; j<list.length; j++){
if(list[j] < list[min]){
min = j;
}
int smallernumber = list[i];
list[i] = list[min];
list[min] = smallernumber;
}
}
}
public static void main (String [] args){
int[] list = {5,4,2,1,3};
System.out.println("Before Sort" + Arrays.toString(list));
SelectionSort1(list);
System.out.println("After Sort " + Arrays.toString(list));
}
My output is:
Before Sort[5, 4, 2, 1, 3]
After Sort [2, 3, 1, 4, 5]
Can anyone point me in the right direction?

Your understanding is almost correct, it compares the element[minimum] with the next elements element[j] and if element[j] < element[minimum] then the minimum index is equal to j. Then it repeats until j reaches the end of the array. After it swaps the index at element[i] with element[minimum].
What this is doing is swapping element[i] with the smallest number to the right of index i. Then moving index i to the next spot. Repeating this gives you a sorted array.
TLDR:
Move the swapping outside of the second for loop. It should be:
public static void SelectionSort1(int[] list){
for (int i = 0; i < (list.length - 1); i++){
int min = i;
for (int j = i + 1; j<list.length; j++){
if(list[j] < list[min]){
min = j;
}
}
int smallernumber = list[i];
list[i] = list[min];
list[min] = smallernumber;
}
}

Related

Test Cases fail to satisfy

I'm just a beginner. I came across this question for which my code fails to satisfy all/most of the test cases.
Question:
Given an array of numbers, find the number of non-empty sub-arrays in which the minimum and maximum element are identical.
Example:
Input: Array = [1, 1, 3]
Output: 4
Explanation:
The required sub-arrays are [1], [1], [3], [1,1]
My solution:
Sort the array and solve the problem.
Code:
for(int i = 0; i < testCases; i++){
int arraySize = in.nextInt();
int array[] = new int[arraySize];
for(int j = 0; j < arraySize; j++){
array[j] = in.nextInt();
}
temp[i] = (findSubArrays(array));
}
for(int i = 0; i < testCases; i++){
System.out.println(temp[i]);
}
private static int findSubArrays(int[] array) {
Arrays.sort(array);
//Since each element can form a sub-array of its own
int noOfSubArrays = array.length;
for(int i = 0; i < array.length-1; i++){
if(array[i] == array[i+1]){
noOfSubArrays++;
}
}
return noOfSubArrays;
}
So you're sorting the array to keep begin points and end points adjacent so you don't need a nested traversal. That makes sense. The problem is that you're counting adjacent duplicates, but what you really need is T(n), or the triangle number of consecutive duplicates. Consider a simple scenario:
[1, 1, 1]
Your algorithm returns 5, but there are actually 6 subsets (by start & end index):
0, 0
0, 1
0, 2
1, 1
1, 2
2, 2
So let's update the algorithm to calculate the triangle number of each sequence:
private static int findSubArrays(int... array) {
Arrays.sort(array);
int sequenceCount = 0;
int total = 0;
for (int i = 0; i < array.length + 1; i++) {
if (i == array.length || (i > 0 && array[i] != array[i - 1])) {
total += triangle(sequenceCount);
sequenceCount = 0;
}
sequenceCount++;
}
return total;
}
private static int triangle(int n) {
return (n * (n + 1)) / 2;
}
Now calling findSubArrays(1, 1, 1) returns 6 and findSubArrays(1, 1, 3) returns 4.

Modified selection sort that selects the biggest number

I am trying to write a modified selection sort that selects the biggest number and place it at the end of a list. I ran into a problem. The code is kind of sorting the list but not perfectly. This is the result after I ran the code:
Before selection sort: [2, 8, 7, 1, 3, 5, 9, 4, 6]
After selection sorted: [1, 2, 8, 7, 3, 4, 5, 9, 6]
Here is my code:
public static int[] sort(int[] list) {
int i, j, maxNum, maxInde, temp = 0;
for (i = list.length-1; i >= 0; i--) {
maxNum = list[i];
maxInde = i;
for (j = i; j < list.length; j++) {
if (list[j] < maxNum) {
maxNum = list[j];
maxInde = j;
}
}
if (maxNum < list[i]) {
temp = list[i];
list[i] = list[maxInde];
list[maxInde] = temp;
}
}
return list;
}
I don't know where the issue is located.
The algorithm is conceptually flawed because you scan the array from n-1 downto 0 and at each iteration select the max element from the subarray a[n-1,...,i]. This subarray should always be sorted (and should consist of the n-i largest elements of the array) ---this is analogous to the loop invariant of the classical selection sort---and the max element to be inserted in the current position should come from the other subarray, i.e., a[i,...,0].
Also, as mentioned in the comments, there is no need to return the array because the algorithm can just modify it.
Here is the fixed version:
int i, j, maxNum, maxInde, temp = 0;
for (i = list.length-1; i >= 0; i--) {
// you start iterating from the end of the list
// which means that the elements between i and the end of the list are sorted
maxNum = list[i];
maxInde = i;
for (j = 0; j < i; j++) {
// you have to iterate through the nonsorted elements
if (list[j] > maxNum) {
maxNum = list[j];
maxInde = j;
}
}
if (maxNum > list[i]) {
// if you found an element that is bigger then the current element
// then it should be set as the current element
temp = list[i];
list[i] = list[maxInde];
list[maxInde] = temp;
}
}
public static void sortArray (int [] a) {
//find max value in this array
for (int i = 0; i < a. length; i++) {
int max=a[0];
int index=0;
for (int j=0; j<a. length-i; j++) {
if (a[j] >max) {
max=a[j];
index=j;
}
}
//change the index
a[index]=a[a.length-(i+1)];
a[a.length-(i+1)]=max; //max value change the last element
}
}
public static void main (String args[]) {
int [] a= {91,13,53,64,48,49,99,35,65,38,62,72};
System.Out.Println (Arrays.toString (ar));
sortArray(ar);
System.Out.Println (Arrays.toString (ar));
}
}

Static methods and Jagged Arrays

I am trying to write a static method that returns an integer, takes a 2-dimensional array of integers as a parameter and return the index of the row in the 2-d array (jagged arrays) that has the largest sum of all its elements. Something went wrong along the line and im still trying to figure out. Help please?
Here is the code:
public static int findMaxRow(int[][] maxRows){
newI= 0;
newJ= 0;
for(int i=0; i< maxRows.length; i++) {
newI += i;
for(int j=0; j< maxRows.length; j++) {
newJ += j;
`` if( newI > newJ){
return newI;
else {
}
}
}
}
You never define the type for newI or newJ, that can be fixed by preceding their declaration with their intended type (i.e int). You also have two " ` " before your if statement, and your missing a closing bracket " } " before your else statement. But those are just syntactical errors. Once you fix those errors you're going to notice that your method is not returning the desired results.
Looking at your code, specifically the for loops.
for(int i=0; i< maxRows.length; i++) {
newI += i;
for(int j=0; j< maxRows.length; j++) {
newJ += j;
// other stuff
}
}
Let's say that maxRows.length equals 3. That means the outer loop is going to run from 0 to 2, so newI will equal 3. Meanwhile for each iteration the outer loop makes, the inner loop iterates 3 times. So newJ will end up equalling 9. Which is not the right way to go about summing the elements of an array. A better way to go about it, is to iterate over the arrays in the outer loop and sum the elements in the inner loop, then make a comparison completing the outer loop. Like so:
int largestRow = 0;
int largestSum = 0;
int sum;
// iterate over each array
for(int i=0; i< maxRows.length; i++) {
sum = 0; // set and reset sum to zero
// iterate over each element
for(int j=0; j< maxRows[i].length; j++) {
sum += maxRows[i][j];
}
// if sum is > the previous largest sum then set largest
// sum to this new sum and record which row
if(sum > largestSum) {
largestRow = i;
largestSum = sum;
}
}
return largestRow;
Here is an example of what you're trying to accomplish.
public class RowSums {
public static void main(String[] args) {
int[][] test = { {1, 5, 7, 0, 9} , {2, 4, 5, 6, 7} , {9, 2, 0, 12, 8, 3} };
System.out.println(printRows(test));
System.out.println("The row with the largest sum is row "
+ findMaxRow(test));
}
public static int findMaxRow(int[][] maxRows){
int largestRow = 0;
int largestSum = 0;
int sum;
// iterate over each array
for(int i=0; i< maxRows.length; i++) {
sum = 0; // set and reset sum to zero
// iterate over each element
for(int j=0; j< maxRows[i].length; j++) {
sum += maxRows[i][j];
}
// if sum is > the previous largest sum then set largest
// sum to this new sum and record which row
if(sum > largestSum) {
largestRow = i;
largestSum = sum;
}
}
return largestRow;
}
public static String printRows(int[][] rows) {
StringBuilder s = new StringBuilder("Rows and their sums:\n");
int sum;
for(int x = 0; x < rows.length; x++) {
s.append("Row [" + x + "] = [ ");
sum = 0;
for(int y = 0; y < rows[x].length; y++) {
s.append(rows[x][y] + " ");
sum += rows[x][y];
}
s.append("]\n");
s.append("Row [" + x + "]'s sum is " + sum + "\n");
}
return s.toString();
}
}
Output:
Rows and their sums:
Row [0] = [ 1 5 7 0 9 ]
Row [0]'s sum is 22
Row [1] = [ 2 4 5 6 7 ]
Row [1]'s sum is 24
Row [2] = [ 9 2 0 12 8 3 ]
Row [2]'s sum is 34
The row with the largest sum is row 2
Modifying your program, the following example will return the index of the row that has the largest sum of elements in it.
Let us suppose our array to be passed is:
int [][] maxRows = {{1,2,3}, {1,2,3,4,5}, {9,9,9,9}, {1,2}};
passing this array in the method
public static int findMaxRow(int[][] maxRows){
int sum = Integer.MIN_VALUE;
int biggestIndex= 0;
for(int i = 0; i<maxRows.length; i++){
int temp = 0;
for(int ir : maxRows[i]){
temp+=ir;
}
if(temp>sum){
sum = temp;
biggestIndex = i;
}
}
return biggestIndex;
}
The above program will return the index of the inner array which has the largest sum of elements, in above case, it will return 2 .

Bubble Sort compiling but out of bounds

I am having issues with getting a simple bubble sort of an array to work properly.
It compiles, but I'm getting an out of bounds exception when running the program.
I know what an out of bounds error is but I can't see why it occurred in this case.
Any geniuses there that know how to fix this? Thank you
public class BubbleSort
{
public static void main(String[] args)
{
// create the array that we want to sort with buble sort alogorithm
int intArray[] = new int[]{5, 90, 35, 45, 150, 3};
//print the array before the bubble sort
System.out.println("Array before Bubble Sort");
for (int i = 0; i < intArray.length; i++)
{
System.out.print(intArray[i] + " ");
}
// sort an array using bubble sort algorithm
bubbleSort(intArray);
System.out.println("");
// print array after sorting using bubble sort
System.out.println("Array after Bubble Sort");
for (int i = 0; i < intArray.length; i++)
{
System.out.print(intArray[i] + "");
}
}
private static void bubbleSort(int[] intArray)
{
int n = intArray.length;
int hold = 0;
for (int i = 0; i < n; i++) //allows us to pass or loop around array
{
for (int j = 1; j < (n - i); j++) //allows on pass or comparison
{
if (intArray[j] > intArray[j + 1]) //swap the elements!
{
hold = intArray[j];
intArray[j] = intArray[j + 1];
intArray[j + 1] = hold;
}
}
}
}
}
In the first iteration of the outer loop, i==0.
Therefore in the inner loop j would go from 1 to n-i-1==n-1.
When j==(n-1), intArray[j+1] would throw ArrayIndexOutOfBoundsException.
On the first iteration of the outer loop of your bubbleSort method, when i is equal to zero, j is allowed to go up to n-i-1, inclusive, i.e. the last value of j is going to be n-1.
When this happens, inArray[j+1] will be out of bounds, because it would be equivalent to inArray[n]. The last valid index is n-1.
to fix this, make sure that the outer loop starts at i=1 instead of i=0.
I commented on the lines where you made a mistake
public static class BubbleSort { //you need static here
public static void main(String[] args) {
int intArray[] = new int[] { 5, 90, 35, 45, 150, 3 };
System.out.println("Array before Bubble Sort");
for (int i = 0; i < intArray.length; i++) {
System.out.print(intArray[i] + " ");
}
bubbleSort(intArray);
System.out.println("");
System.out.println("Array after Bubble Sort");
for (int i = 0; i < intArray.length; i++) {
System.out.print(intArray[i] + " "); // you need space between the parenthesis so that results show up readable
}
}
private static void bubbleSort(int[] intArray) {
int n = intArray.length;
int hold = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < (n - i - 1); j++){ // j has to be equal to 0, or your first value in the array won't get compared, and -1 because of the array out of bounds error
if (intArray[j] > intArray[j + 1]){
hold = intArray[j];
intArray[j] = intArray[j + 1];
intArray[j + 1] = hold;
}
}
}
}
}
public class BubbleSort
{
public static void main (String[]args)
{
// create the array that we want to sort with buble sort alogorithm
int intArray[] = new int[] {5, 90, 35, 45, 150, 3};
//print the array before the bubble sort
System.out.println ("Array before Bubble Sort");
for (int i = 0 ; i intArray[j+1]) //swap the elements!
{
hold = intArray[j];
intArray[j] = intArray[j + 1];
intArray[j + 1] = hold;
}
}
}
}
}
Replace j < (n-i) with j < (n-i)-1.
Reason
In the last iteration, j will have a value equal to one less than the length of the array(ie it points to the last element). But when you compare elements with index j+1, you are pointing to an out of bound element. Thus the exception. Hope it helps.
(this is to answer your question about 3 not being the first value displayed)
code should go like this if you want in assenting order
you have missed for( int j=0; j<(n-i-1); j++
for (int i=0; i<n; i++) //loop trough array
{
for( int j=0; j<(n-i-1); j++) //loop allows variable j pass on for comparison
{
if ( intArray[j]> intArray[j+1]) // if current slot in array j is bigger than the next one

Count the Number of Swaps in Selection Sort

I've read through all the discussions trying to find an answer but none of the answers have worked for me so I'm trying it this way.
public static int SelectionSort(long[] num)
{
int i, j, first;
long temp;
int swap = 0;
int pass = 0;
int count = 0;
boolean Mini = false;
for (i = num.length - 1; i > 0; i--)
{
for(int k = 0; k < num.length; k++)
{
System.out.println(" k = " + k
+ " \t X[i] = " + num[k] + " swap count: " + swap);
}
System.out.println("");
first = 0; //initialize to subscript of first element
for(j = 1; j <= i; j ++) //locate smallest element between positions 1 and i.
{
if(num[j] < num[first])
{
first = j;
//Mini = true;
}
}
//if(Mini){
// swap++;
//}
temp = num[first]; //swap smallest found with element in position i.
num[first] = num[i];
num[i] = temp;
}
return swap;
}
Using a simple array as my test case:
long[] X = {1, 4, 3, 2, 5};
The number of swaps should only equate to 1 because it's swapping the first and last elements only. However, it isn't working. While I know my if condition doesn't work, I can't think of what would. I can't seem to work the logic that it increments a swap when items are actually swapped.
Why not increment the counter when you actually perform a swap?
//swap smallest found with element in position i.
swap++
temp = num[first];
num[first] = num[i];
num[i] = temp;
EDIT:
Good point in the comment. The current code still performs a superfluous swap if the array is sorted (i.e., first and i are the same):
if (first != i) {
swap++
temp = num[first];
num[first] = num[i];
num[i] = temp;
}
With your implementation you will always have n swaps (where n is the number of elements in your array).
What I think you want is to only perform a swap when it actually makes a difference ... so when "first" and "i" have different values. Otherwise you switch the element with itself.
if (first != i) {
temp = num[first];
num[first] = num[i];
num[i] = temp;
swapp++;
}

Categories