I have a selection sort implemented to sort an array of random integers. I would like the user to choose between ascending or descending order. The ascending sort works flawlessly, although descending does not. Here is what my selection sort looks like:
public String selection(int[] array,int num,String order) {
String output = "";
int min;
// This is the descending selection sort
if (order == "desc") {
for (int i = num - 1; i >= 0; i--) {
// Assume first element is min
min = i;
for (int j = i + 1; j < num; j++) {
if (array[j] < array[min]) {
min = j;
}
}
if (min != i) {
final int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
output = output + Integer.toString(array[i]) + "\n";
}
} // This is the ascending selection sort
else {
for (int i = 0; i < num; i++) {
// Assume first element is min
min = i;
for (int j = i + 1; j < num; j++) {
if (array[j] < array[min]) {
min = j;
}
}
if (min != i) {
final int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
output = output + Integer.toString(array[i]) + "\n";
}
}
return(output.trim());
}
I've seen a few questions similar to mine, although none of the questions I saw had their selection sort set up like this so I was unable to implement their solutions.
Firstly, the if blocks should compare to minPosition and maxPosition, not i. Secondly, if you are selecting both minimum and maximum, then your inner for loop should stop at a.length - i, not a.length (since the top i elements are also sorted). Doing both gives you this as the ascending order algorithm.
public static void SortAscending(int[] a){
for(int i = 0; i < a.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length - i; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
/*
if(i < a.length/2-1)
*/
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
To switch to descending order, simply add one line.
public static void SortDescending(int[] a){
for(int i = 0; i < a.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length - i; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
/*
if(i < a.length/2-1)
*/
swap(a,minPosition,maxPosition); // <-- this line
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
Use swap function https://www.geeksforgeeks.org/collections-swap-method-in-java-with-examples/
Related
Could you please help identify what sorting method is this?
public static int[] sort(int arr[]) {
int temp1 = 0;
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr));
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
temp1 = arr[i];
arr[i] = arr[j];
arr[j] = temp1;
}
}
}
return arr;
}
Neither. It is close to selection sort, but makes unnecessary swaps.
Bubble sort makes pair-wise swaps on subsequent elements, until the "lightest" element is at top, like a bubble goes up in fluid.
int unorderedLen = arr.length;
do {
int newUnorderedLen = 0;
// after a cycle, largest element will be at top
for (int i = 1; i < unorderedLen; j++) {
if (arr[i-1] > arr[i]) {
newUnorderedLen = i;
swap(arr, i, i-1);
}
}
unorderedLen = newUnorderedLen;
} while (unorderedLen > 0);
Selection sort searches and selects the place where an element should fit and makes a single swap after.
// at i. cycle, we select i. least element and place at i.
for (int i = 0; i < arr.length-1; i++) {
int minIndex = i;
// search for least element in the remaining unsorted
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
if (minIndex != i) {
swap(arr, minIndex, i);
}
}
I need to make a programm in java with the selection sort algorithm. So i tried this to do that but the code doesn't works.
Problem with this code is that it doesn't swap numbers. Instead, it replaces array[i] with the minimum number found. You can modify your loop like this to do the swapping.
for (int i = 0; i < array.length; i++) {
int minIndex = i;
for (int j = i; j < array.length; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
if (array[minIndex] != array[i]) {
int wert = array[minIndex];
array[minIndex] = array[i];
array[i] = wert;
}
}
For selection sort use this method
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;
}
}
If you need an ascend order just use:
Arrays.sort(array) from java.util library
But if you need to sort descending I'd suggested to reffer to:
https://www.baeldung.com/java-sorting-arrays
What is wrong in my bubble sort in ArrayList? It was not sorted . I am a beginner.
public static ArrayList < Integer > bubbleSort(ArrayList < Integer > ar) {
for (int i = 0; i < ar.size() - 1; i++) {
int indexMax = i;
for (int j = 1; j < ar.size(); j++) {
if (ar.get(indexMax) > ar.get(j)) {
indexMax = j;
}
}
if (indexMax != i) {
int temp = ar.get(i);
ar.set(i, ar.get(indexMax));
ar.set(indexMax, temp);
}
}
return ar;
}
Are you sure you should start from 2nd element (j=1) every time?
Try j=i. i.e.,
public static ArrayList<Integer> bubbleSort (ArrayList<Integer> ar) {
for (int i = 0; i < ar.size() - 1; i++) {
int indexMax = i;
for (int j = i; j < ar.size(); j++) {
if (ar.get(indexMax) > ar.get(j)) {
indexMax = j;
}
}
if (indexMax != i) {
int temp = ar.get(i);
ar.set(i, ar.get(indexMax));
ar.set(indexMax, temp);
}
}
return ar;
}
P.S this will sort your array in ascending order.
Your swapping code block looked like it was outside of loop, so the only one swap occurred for one iteration of main loop.
You are also doing unnecessary comparing of elements, starting your inner loop with precondition j = 1. You should start it from i, as after some iterations of outer loop range from 0 to i will be already sorted.
I think you can use a simpler approach.
for (int i = 0; i < ar.size() - 1; i++) {
for (int j = i; j < ar.size(); j++) {
if (ar.get(j) < ar.get(i)) {
Integer temp = ar.get(j);
ar.set(j, ar.get(i));
ar.set(i, temp);
}
}
}
As you can see, swapping takes place inside of the inner loop, and it also skips already sorted part of collection.
You can do sorting like this:
for(int out=inputArray.size()-1; out>0; out--){
for(int j=1; j<=out; j++){
if(inputArray[j-1]<inputArray[j]){
//Swap the elements
int temp = inputArray[j];
inputArray[j]=inputArray[j-1];
inputArray[j-1]=temp;
}
}
}
return inputArray;
Can you try that?
int n = arr.length;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
{
// swap arr[j+1] and arr[i]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
I am trying to create a selectionSort method to arrange values in descending order. This code arranges them in ascending order. How can I swap this code to arrange it the other way.
public void selectionSort()
{
int n = data.length;
for(int index = 0; index < n-1; index++)
{
int min_idx = index;
for(int j = index+1; j < n; j++)
if(data[j] < data[min_idx])
min_idx = j;
int temp = data[min_idx];
data[min_idx] = data[index];
data[index] = temp;
}
}
As of now I can think of two methods. I haven't tried them but worth giving a try.
Multiply all the numbers by -1 and apply the original selection sort to sort for ascending order. After sorting is complete multiply all the numbers by -1 to get back originwl numbers but now they are sorted in descending order.
Try changing the comparison condition
if(data[j] < data[min_idx])
to
if(data[j] >= data[min_idx])
Let me know if there is some issue with these methods.
Instead of selecting the minimal item in each iteration, you should instead select the maximum one. All you really need to do is change the < condition to >, but I've also changed the names accordingly to make the code easier to understand:
public void selectionSort()
{
int n = data.length;
for(int index = 0; index < n-1; index++)
{
int max_idx = index; // max_idx instead of min_idx
for(int j = index+1; j < n; j++)
if(data[j] > data[min_idx]) // > instead of <
max_idx = j;
int temp = data[max_idx];
data[max_idx] = data[index];
data[index] = temp;
}
}
To solve this problem, I would reccomend you to refactor your code first. Move swap and findMin into separate method:
private static int getMin(int[] arr, int from, int to) {
int min = from;
for (int j = from; j < to; j++)
min = arr[j] < arr[min] ? j : min;
return min;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
Here, you probably can see, that implementation of ASC and DESC sorting are trivial:
public static void selectionSortAsc(int[] arr) {
for (int i = 0; i < arr.length - 1; i++)
swap(arr, getMin(arr, i + 1, arr.length), i);
}
public static void selectionSortDesc(int[] arr) {
for (int i = arr.length - 1; i > 0; i--)
swap(arr, getMin(arr, 0, i + 1), i);
}
public static class SelectionSort
{
static int min;
public static void Sort(int[] data)
{
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < data.Length; j++)
{
min = j;
if (data[i] < data[j])
Swap(x: ref data[i], y: ref data[min]);
}
}
}
private static void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
}
For Ascending this line
if (data[i] < data[j])
For Descending this line
if (data[i] > data[j])
So here I have a selection sort to order values from lowest to highest, how would I change that so it orders the values from highest to lowest?
int min;
for (int i = 0; i < array.length; i++) {
// Assume first element is min
min = i;
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[min]) {
min = j;
}
}
if (min != i) {
final int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
itsATextArea.append(array[i] + "\n");
}
You just need to change the signs in the code
if (array[j] > array[max])
{
//assign it here
max = j;
}
following is how the code looks after the modification.
int max;
for (int i = 0; i < array.Length; i++)
{
// Assume first element is max
max = i;
for (int j = i + 1; j < array.Length; j++)
{
if (array[j] > array[max])
{
max = j;
}
}
if (max != i)
{
int temp = array[i];
array[i] = array[max];
array[max] = temp;
}
}
How about:
java.util.Arrays.sort(array);
java.util.Arrays.reverse(array);