I have a question about bubble sort using an array. Here is some example code:
public class SortArray
{
public static void main(String[] args)
{
int[] arr = {4,6,4,2,764,23,23};
sort(arr);
}
static void sort(int[] arr)
{
int k;
for(int i = 0; i < arr.length; i++)
{
for(int j = i; j < arr.length-1; j++)
{
if(arr[i] < arr[j+1])
{
k = arr[j+1];
arr[j+1] = arr[i];
arr[i] = k;
}
}
System.out.print(arr[i] + " ");
}
}
}
There are two loops for checking the array, I understand the first loop is to go through each element in array, but how about the second one? Why is j starting from i and why is it going up to the length minus 1?
Additionally, can I use bubble sort to sort an ArrayList?
What you have there is called selection sort, not bubble sort.
Bubble sort only swaps adjacent elements, but you're going though the rest of the array and finding the minimum, which is exactly what selection sort does.
Since you use arr[j+1], you can rewrite the inner loop to use arr[j] and shift up the range by one, like this:
for(int j = i + 1; j < arr.length; j++)
{
if(arr[i] < arr[j])
{
k = arr[j];
arr[j] = arr[i];
arr[i] = k;
}
}
Now it's a bit more clear that you're looking at each other remaining element to find the minimum.
Yes, you can modify any sort that works on arrays to sort an ArrayList instead by just using ArrayList.get instead of array accesses and ArrayList.set instead of array assignments, i.e.:
for(int i = 0; i < arr.size(); i++)
{
for(int j = i + 1; j < arr.size(); j++)
{
if(arr.get(i) < arr.get(j))
{
int k = arr.get(j);
arr.set(j, arr.get(i));
arr.set(i, k);
}
}
}
Note that both selection sort and bubble sort are fairly inefficient (O(n^2)), there are more efficient sorting algorithms such as quick-sort or merge-sort (running in O(n log n)).
The first loop holds an element in i and the second one examines each element after i, namely j and compares it to the i it has holded. If they can be swapped, the algorithm swaps their positions and moves on. When the outer loop finishes an iteration, all elements prior to i are sorted, so j starts from i.
Do this once on paper and it all makes sense.
EDIT: As you have completed your algorithm, the reason for the second loops condition, is that you swap i with j+1. So if your j goes on to the last element of the array, the next element wouldn't exist and raises an exception. Also you can use this code to sort ArrayList. Just change the code swapping values with the appropriate setters and getters.
Related
Hello there! At the moment, I am just a tad bit confused with my code. I'd like to move my array in descending order. This sounds very simple but for some reason I cannot wrap my head around this method. Currently, this is a selectionSort method I wrote that goes directly in ascending order. I'm not sure where to start when it comes to descending order.. as to how to reverse the equations, I usually end up overflowing since it's supposed to be using the original ".length" of the array.
Thank you very much for any help!
int[] arr = {5, 3, 2, 44, 1, 75, 23, 15};
private static void descendingSort (int[] arr) {
for ( int i = 0; i < arr.length - 1; i++) {
int smallestIndex = i;
for ( int j = i + 1; j < arr.length; j++) {
//searching for smallest...
//if statement declaring if arr is smaller than the index[0]
if (arr[j] < arr[smallestIndex]) {
//now it has changed to pickle because it has swapped. thx u
smallestIndex = j;
}
}
}
}
If you want to solve the problem fast, here's how you approach it.
Notice we just change a few lines.
Specifically ...
We still find the smallest element
We put it in the back and not the front
The iteration order in both loops is back-to-front and not front-to-back
An easier way to implement this would be to just sort the elements in ascending order and then just reverse the array.
void selectionSortDescending(int arr[])
{
int n = arr.length;
// Start by finding the smallest element to put in the very back
// One by one move boundary of unsorted subarray
for (int i = n-1; i >= 0; i--)
{
// Find the minimum element in unsorted array
int min_idx = i;
for (int j = i-1; j >= 0; j--)
if (arr[j] < arr[min_idx])
min_idx = j;
// Swap the found minimum element with the last element
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
i want to implement a selection sort method that takes an array of ints and sorts it in a descending order. however, the trick is to keep the original selection sort method unchanged but instead using simple arithmetic operations and without adding extra loops to swap the elements after the array finished sorting. this is my code and the idea is to store the position of the maximum value and the minimum value in local variables and swap them with the corresponding position after the inner loop finishes iteration. i even tried using a only one variable to find the lowest value and put it at the end of the array but i failed and i am getting the wrong results and i need help spotting the error. here is my code
public static void newSortMethod(int[]a){
for(int i = 0; i < a.length-1; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
System.out.println();
}
public static void swap(int[]a, int i, int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
int[] a = {2,6,3,9,5,4,8,7,0,13,-3,1};
newSortMethod(a);
}
here is the output of the program so far
-3 8 2 9 13 5 4 6 3 1 7 0
Your original algorithm is wrong. 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 newSortMethod(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;
}
}
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
To switch to descending order, simply add one line.
public static void newSortMethod(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;
}
}
swap(a,minPosition,maxPosition); // <-- this line
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
Errors
First off, let’s look for problems in your code. There’s a few, which happens a lot in programming.
Your code is still trying to sort ascending with swap(a,minPosition,i), and then trying to put the maximum value at the end, which isn’t what you want: you want to put maximum values at the beginning.
Your n is never modified, so you’ll keep printing 0.
Sample solution
Now let’s see something that works. I’m not totally sure what your ascending selection sort looked like, but I imagine it should be something like this:
public static void ascendingSortMethod(int[]a){
int n = 0; // this is only to count how many times the swap method was called
for(int i = 0; i < a.length-1; i++){
int minPosition = i;
for(int j = i+1; j < a.length; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
}
if(minPosition != i){ // check whether swap is necessary
swap(a,minPosition,i);
n ++;
}
}
System.out.println(n);
}
To make it sort in descending order, just switch the comparison operator (and possibly the minPosition identifier for clarity).
public static void newSortMethod(int[]a){
int n = 0; // this is only to count how many times the swap method was called
for(int i = 0; i < a.length-1; i++){
int maxPosition = i;
for(int j = i+1; j < a.length; j++){
if(a[j] > a[maxPosition]){ // switched comparison operator
maxPosition = j;
}
}
if(maxPosition != i){ // check whether swap is necessary
swap(a,maxPosition,i);
n ++;
}
}
System.out.println(n);
}
I have a class and right now we are doing insertion sort. I think my code worked properly but my professor said not to embed one of my loops (it shifts the values in my array over) and that it should be done while "searching".
public static void insertionSort(int array[]) {
int n = array.length;
for(int i = 0; i < n; i++) {
int nextIndex = i;
for(int j = 0; j < i; j++) {
if(array[nextIndex] < array[j]) {
int temp = array[nextIndex];
// ********************************
for(int k = i; k > j; k--) {
array[k]=array[k-1];
}
// ********************************
array[j]=temp;
j = i
}
}
}
}
What's wrong with the above?
I think what your professor meant is this: You are currently looking through the sorted part of your array [0..i] from bottom to top to find the position at which the new element should be inserted. Afterwards you move through your array from top to bottom to shift the new element to the right position.
Instead, you could just move the new element through the element and simultaneously look for the right position, similar to Bubblesort, if you know the algorithm. This saves you this for-loop your prof marked.
What does the following piece of java code do?
public static void dontknow(int[] a){
for (int i = 0; i < a.length; i++){
for (int j = a.length-1; j > i; j--)
{
if (a[j-1] > a[j])
{
int T = a[j-1];
a[j-1] = a[j];
a[j] = T;
}
}
}
}
This is a rather weird implementation of Bubble Sort to sort the int array contents by size. Albeit a rather stupid one as it doesn't stop when the array is sorted, but always makes the max. number of passes (a.length iterations).
This is the Bubble Sort algorithm. It sorts the array in a efficient way.
I'm looking for a bubblesort code in java that is opposite of the usual thing that I'm seeing when I search the internet.
I don't really understand the code below, all I know is that it sorts a bunch of numbers from lowest to highest. Is the code below modifiable so that instead of outputting the numbers from lowest to highest. It outputs it as highest to lowest?
int i;
int array[] = {12,9,4,99,120,1,3,10};
System.out.println("Values Before the sort:\n");
for(i = 0; i < array.length; i++)
System.out.print( array[i]+" ");
System.out.println();
bubble_srt(array, array.length);
System.out.print("Values after the sort:\n");
for(i = 0; i <array.length; i++)
System.out.print(array[i]+" ");
System.out.println();
System.out.println("PAUSE");
}
public static void bubble_srt( int a[], int n ){
int i, j,t=0;
for(i = 0; i < n; i++){
for(j = 1; j < (n-i); j++){
if(a[j-1] > a[j]){
t = a[j-1];
a[j-1]=a[j];
a[j]=t;
}
}
}
}
change
if(a[j-1] > a[j]){
to
if(a[j-1] < a[j]){
you could change the bubblesort to satisfy your needs or leave it as is and walk the sorted array backwards. for both, you should try to understand such a little piece of code instead of simply asking for the modified code.
Some words about your code:
If you move the swap-method out of your inner loop, it get's more readable, and more easy to reason about the independent parts.
public void swap (int i, int j, int [] arr) {
int tmp = arr [i];
arr [i] = arr [j];
arr [j] = tmp;
}
Sweet little methods are easy to understand and test, which is important.
Don't declare the index variables outside the for. This makes it harder to reason about your code - the variables are visible without necessity outside the loop. In the old code, you gain nothing from declaring tmp outside of the inner loop. Declaration is cost-free at runtime.
public static void bubbleSort (int a[], int n) {
for (int i = 0; i < n; i++) {
for (int j = 1; j < (n-i); j++) {
if (a[j-1] > a[j]) {
swap (j, j-1, a);
}
}
}
}
// ... missing ...
Don't repeat yourself. Move duplicated code into a method.
public static void show (int [] arr)
{
for (int i : arr)
System.out.print (i + " ");
System.out.println ();
}
Sweet little methods are easy to test. Use the simplified for-loop, whenever possible, to avoid off-by-one-errors, and to be more robust to code changes - they work for Lists too, for example.
int array[] = {12, 9, 4, 99, 120, 1, 3, 10};
System.out.println ("Values Before the sort:\n");
show (array);
bubbleSort (array, array.length);
System.out.print ("Values after the sort:\n");
show (array);
System.out.println ("PAUSE");
}
With the simplified code, it get's more easy to reason about, what which part does.
if (a[j-1] > a[j]) {
needs just to be changed
if (a[j-1] < a[j]) {
to reverse the order.
for(i = array.length -1; i >=0; i--)
{
System.out.println(array[i]);
}
Should work. You start at the end of the array and go backwards