Skip to content

Rework Bubble Sort C++ #251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ GuyPozner
<br>
William Boyles
<br>
Benjamin Chislett
<br>
86 changes: 27 additions & 59 deletions chapters/algorithms/bubble_sort/code/c++/bubblesort.cpp
Original file line number Diff line number Diff line change
@@ -1,71 +1,39 @@
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <iterator>
#include <random>
#include <stdlib.h> // rand
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do

#include <cstdlib>

#include <vector> // vectors
#include <iostream> // cout
#include <algorithm>// swap

using std::begin;
using std::end;

template <class Rng>
std::vector<float> generate_input(std::size_t size, Rng& rng) {
auto dist = std::uniform_real_distribution<>(0.0, 1.0);

auto ret = std::vector<float>();
std::generate_n(std::back_inserter(ret), size,
[&rng, &dist] { return dist(rng); });

return ret;
}

template <class Iter>
void print_range(std::ostream& os, Iter const first, Iter const last) {
os << '{';

if (first != last) {
os << *first;
std::for_each(first + 1, last, [&os] (double d) { os << ", " << d; });
}

os << "}\n";
}

template <class Iter>
void bubble_sort(Iter const first, Iter const last) {
if (first == last) {
// the empty range is vacuously sorted
return;
}

for (;;) {
std::vector<int> bubble_sort(std::vector<int> unsorted_list) {
Copy link
Contributor

@mika314 mika314 Jul 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would do sort in place

void bubble_sort(std::vector<int>& array)

It will make code more performant (one array copy less) without any degradation of readability.

while (true) {
bool is_sorted = true;

for (auto it = first; it + 1 != last; ++it) {
// these are unsorted! gotta swap 'em
if (*(it + 1) < *it) {
using std::swap;
swap(*it, *(it + 1));
// Sweep through the array
for (unsigned int i = 0; i < unsorted_list.size() - 1; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// If next if smaller, swap, and keep sorting
if (unsorted_list[i + 1] < unsorted_list[i]) {
std::swap(unsorted_list[i], unsorted_list[i + 1]);
is_sorted = false;
}
}

if (is_sorted) {
break;
}
// If we made it through without swapping anything, the list is sorted
if (is_sorted) { return unsorted_list; }
}
}

int main() {
std::random_device random_device;
auto rng = std::mt19937(random_device());

auto input = generate_input(10, rng);
int main()
{
std::vector<int> to_be_sorted = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style minor: = {} just a noise, do:

std::vector<int> to_be_sorted;

// Initialize and print a vector with 50 random integers of domain [0,1000]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is a lie, should be:

// Initialize and print a vector with 50 random integers of domain [0,999]

or

// Initialize and print a vector with 50 random integers of domain [0,1000)

First is preferable.

for (int i = 0; i < 50; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would provide a hand written test sample. Random test set usually does not cover edge cases and gives false confidence about the code.

In this case it does not cover cases with empty array, already sorted array and array with reverse order for instance.

int value = rand() % 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to initialize random generator with

srand(time(nullptr));

std::cout << value << " ";
to_be_sorted.push_back(value);
}
std::cout << std::endl;

std::cout << "before sorting:\n";
print_range(std::cout, begin(input), end(input));
std::vector<int> sorted = bubble_sort(to_be_sorted);

bubble_sort(begin(input), end(input));
for (int i : sorted) { std::cout << i << " "; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add

std::cout << std::endl; 

It is kind of annoying if terminal program does not do it.


std::cout << "\nafter sorting:\n";
print_range(std::cout, begin(input), end(input));
return 0;
Copy link
Contributor

@mika314 mika314 Jul 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style minor: C++ does not require return 0

Really minor, I lot of people prefer return 0, for my taste it is just a noise.

}