C++ Bubble Sort Algorithm - c++

I have the following code written in c++ and the algorithm works when in this scenario. I am knew to c++ and don't understand what I did wrong in my 2nd test.
#include <iostream>
using namespace std;
void bubbleSort(int numbers[], int size) {
for (int i = 0; i<size;i++) {
for (int j=0; j<size;j++) {
if (numbers[j] > numbers[j+1]) {
swap(numbers[j], numbers[j+1]);
}
}
}
}
int main() {
int numbers[] = {7,5,6,4};
bubbleSort(numbers,4);
for (int print = 0; print < 4; print++) {
cout << numbers[print] << endl;
}
return 0;
}
But, fails when I try to put in numbers that are already sorted:
#include <iostream>
using namespace std;
void bubbleSort(int numbers[], int size) {
for (int i = 0; i<size;i++) {
for (int j=0; j<size;j++) {
if (numbers[j] > numbers[j+1]) {
swap(numbers[j], numbers[j+1]);
}
}
}
}
int main() {
int numbers[] = {1,2,3};
bubbleSort(numbers,3);
for (int print = 0; print < 3; print++) {
cout << numbers[print] << endl;
}
return 0;
}

for (int j=0; j<size;j++) {
If size is 3, if the array has three values, for example, this loop iterates with values of j of 0, 1, and 2.
if (numbers[j] > numbers[j+1]) {
When j is 2 this compares numbers[2] with numbers[3].
There is no numbers[3]. This is undefined behavior. The loop is off by 1 value.
Additionally, the overall bubble sort implementation is flawed. In the shown code the inner loop iterates over the entire array (ignoring the off-by-1 bug), every time. In a classical bubble sort the first pass (the first iteration of the outer loop) results in the inner loop iterating over the entire array and "bubbling" the smallest/largest value to the end of the array. On the next pass the inner loop does not need to iterate over the entire array, but only up until the 2nd smallest/largest position of the array. And so on, each pass (the outer loop) results in the inner loop iterating over a smaller, and smaller subset of the array, "bubbling" the corresponding value to the appropriate stop.
In addition to fixing the off-by-1 bug you'll also need to adjust the overall logic of this bubble sort, if you wish to get a perfect grade for your homework assignment.

Implementing bubble sort in its entirety is problematic. In the example code, the inner loop repeatedly iterates over the full array while disregarding the shift by 1. The inner loop iterates over the whole array in a traditional bubble sort's first iteration of the outer loop, "bubbling" the smallest/largest value to the array's end. On the subsequent iteration, the inner loop only has to iterate up to the array's second-smallest/largest point rather than the full array. The inner loop then iterates through a smaller and smaller subset of the array, making bubbles of the associated the associated value to the proper stop with each successive run in the outside loop.

Related

Can you change a pointer in loop?

Let's say I have a vector of integers:
vector<int> v(n);
Which I fill up in a for loop with valid values. What I want to do is to find a index of a given value in this vector. For example if I have a vector of 1, 2, 3, 4 and a value of 2, i'd get a index = 1. The algorithm would assume that the vector is sorted in ascending order, it would check a middle number and then depending of it's value (if its bigger or smaller than the one we're asking for) it would check one of halves of the vector. I was asked to do this recursive and using pointer. So I wrote a void function like:
void findGiven(vector<int> &v){
int i = 0;
int *wsk = &v[i];
}
and I can easily access 0th element of the vector. However I seem to have some basic knowledge lacks, because I can't really put this in a for loop to print all the values. I wanted to do something like this:
for (int j = 0; j<v.size(); j++){
cout << *wsk[j];
}
Is there a way of doing such a thing? Also I know it's recurisve, I'm just trying to figure out how to use pointers properly and how to prepare the algorithm so that later I can build it recursively. Thanks in advance!
The correct way is:
for (int wsk : v) {
cout << wsk;
}
If you insist on pointers:
int* first = v.data();
for (size_t j = 0; j < v.size(); ++j) {
cout << first[j];
}

This sorting array code cause the last element dissapear

So, I tried to make an array using input first, then sorting it out from smallest to biggest, then display the array to monitor.
So I come up with this code :
#include <iostream>
using namespace std;
void pancakeSort(int sortArray[], int sortSize);
int main()
{
// Input The Array Element Value
int pancake[10];
for(int i=0; i<10; i++)
{
cout << "Person " << i+1 << " eat pancakes = ";
cin >> pancake[i];
}
// call pancake sorting function
pancakeSort(pancake, 10);
}
void pancakeSort(int sortArray[], int sortSize)
{
int length = 10;
int temp;
int stop = 10;
// this is where the array get sorting out from smallest to biggest number
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
// after that, the array get display here
for(int x=0; x<sortSize; x++)
{
cout << sortArray[x] << " ";
}
}
but the output is weird :
enter image description here
the function is successfully sorting the array from smallest to biggest,
but there is 2 weird things :
1. The biggest value element (which is 96 from what I input and it's the 10th element after got sorted out), disappear from the display.
2. For some reason, there is value 10 , which I didn't input on the array.
So, what happened?
In the loop
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop is the length of the array, and you are iterating through values of j = 0 to stop - 1. When j reaches stop - 1, the next element that is j+1 becomes stop (10 in this case). But since your array has a length of 10, sortArray[10] is not part of the array, but is referring to some other object in memory which is usually a garbage value. The garbage value is 10 in this case. When you swap sortArray[10] and sortArray[9], the garbage value becomes part of the array and the value at index 9 leaves the array. This keeps on happening till the outer loop ends.
The end result is that unless the garbage value < largest element in the array, the garbage value is pushed in the array and the greatest value of the array is put at sortArray[10] which is not part of the array. If the garbage value is greater than all the values of the array, it'll be found at sortArray[10] which is again not part of the array and your code will return the desired result.
Essentially, what you are doing is giving the function an array of 10 (or stop) elements, but the function is actually working with an array of 11 (or stop + 1) elements, with the last element being a garbage value. The simple fix is to change the conditional of the loop to j < stop - 1.
Note that if you had written this code in a managed (or a comparatively higher level) language like Java or C#, it would have raised an IndexOutOfBoundsException.
At index 9, j+1 is out of bounds. So to fix this, you only need to check till index 8
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop-1; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
Look carefully at the inner loop condition j<stop-1

why sorting alogrithim is going to infinite loop

My code: (i expect it sort passed array into ascending order).
void sort( int arr[], int n) {
int c=0;
for(int i = 0; i<n-1; ++i) {
if (arr[i]>arr[i+1]) {
c=arr[i];
arr[i]=arr[i+1];
arr[i]=c;
i=0;
}
}
}
example array: int arr[4]={3,1,2,4};
sort(arr,4);
Error: Infinite loop???
Your code for swapping two consecutive elements in the array is wrong. Replace the first three lines inside the if statement with:
c = arr[i];
arr[i] = arr[i+1];
arr[i+1] = c;
The last line is the one I fixed.
This algorithm is called a bubble sort.
EDIT: Another thing you need to do to ensure correct sorting is to set i to -1 instead of 0 at the end of the if statement. If you just set it to 0, then on the next iteration of the loop it will get incremented and become 1, which means that your code will not consider swapping the first two elements of the loop. (Thanks to the comment from Anton Savin.)

Sorting array with BubbleSort

l changed my code but still cant figure out why it wont sort array...bubble sort only moves all elements one place to the right in my program instead of sorting array...l tired bsort and ssort and both do same thing shift elements for 1 position
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void bsort(int n,int a[])
{
int i,j,k;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1;j++)
{
if(a[j]>a[j+1]);
{
k=a[j+1];
a[j+1]=a[j];
a[j]=k;
}
}
}
}
int main()
{
int i,j,k,m,n;
srand(time(0));
printf("Unesi broj clanova niza:");
scanf("%d",&n);
int a[n];
printf("Niz za sortiranje je:\n");
for(int i=0;i<n;i++) //Generisanje niza
{
a[i]=rand()%(81);
}
for(int i=0;i<n;i++)
{
printf("%3d",a[i]);
}
bsort(n,a);
printf("\n\nSortirani niz je:\n");
for(i=0;i<n;i++)
{
printf("%3d",a[i]);
}
}
There are several problems with your bubble sort implementation.
First, this line:
if (a[j] > a[j + 1]); {
is incorrect. The semi-colon terminates the conditional. As a result, the following block executes on every iteration of the inner loop and you end up unconditionally swapping a[j] and a[j+1] for every value of j. This means you're performing a nonsensical rearrangement of the array.
Second, you're not dealing correctly with edge cases in the inner loop. When j == 19, you access a[j+1], which is a[20], which is beyond the end of the array. You thus import garbage data into your array.
Lastly, even after correcting the above, your implementation is needlessly inefficient, in that your inner loop goes through the entire array on each iteration of the outer loop, which it doesn't have to. Hint: Try to think about how the initialization or termination condition of the inner loop could depend on i.
Update (after the OP's rewrite): You only addressed the second issue.
int main() {
int a[20];
srand(time(0));
// array values initialization
for (int i = 0; i < 19; i++) {
a[i] = rand() % (81);
}
// array sorting
bsort(a);
// array printing
for (int i = 0; i < 19; i++) {
printf("%3d", a[i]);
}
}

Error with data store in vector in C++

I try to make a list of digit of consequence number from 1 to 100; for example, 123456789101112..... However, when I print out the result from the list_result; there is some strange number in my list_result vector. Here the following code:
int main()
{
vector<int> list_num;
vector<int> list_result;
int count =0;
for(int index = 1; index<=100; index++)
{
count = index;
if(index<10)
{
list_result.push_back(index);
}
else
{
while(count!=0)
{
list_num.push_back(count%10);
count=count/10;
}
for(int i=0; i<=list_num.size();i++)
{
list_result.push_back(list_num[list_num.size()-i]);
}
list_num.clear();
}
for(int i = 0; i<=list_result.size(); i++)
{
cout<<list_result[i];
}
}
return 0;
}
Anyone has any ideas? Thank,
Your program exhibits undefined behavior.
for(int i=0; i<=list_num.size();i++)
{
list_result.push_back(list_num[list_num.size()-i]);
}
Valid indexes into list_num are 0 through list_num.size()-1. Yet on the first iteration of this loop, when i == 0, you attempt to access list_num[list_num.size()]. There is no such element.
Igor Tandetnik described an issue in the for loop inside the else block, but I've identified another issue, this time in the output stage of the program.
Remember that indices are zero-based, which means they run from zero to the number of elements minus one. vector::size() returns the total number of elements, in this case 100. Because you're comparing this value with the index using a less-than-or-equal inequality, you end up trying to access element 100 on the final iteration of the loop, and element 100 does not exist since the range of valid indices is 0 to 99. When writing a loop that iterates through an array or vector, you should always compare indices with array/vector sizes using strict inequalities.
In the final for loop, replace the <= with a strict < comparison so that it stops at the actual last element and not afterwards:
for(int i = 0; i<list_result.size(); i++)
{
cout<<list_result[i];
}
Wikipedia has an easy-to-understand explanation of this common programming mistake, known as an off-by-one error.