bucket sort gives the wrong results - c++

I have been trying to implement bucket sort using large size of random numbers example:"rand()%1000000
the issue is the results I get are wrong and are not listed correctly here is my code for bucket sort
void binsort(int arr[], int n){
int maxsize = 1000000;
int *b = new int[maxsize];
for( int i = 0; i <= maxsize;i++){
b[i] = 0;
}
for( int i = 0; i <n;i++){
b[arr[i]]++;
}
for(int j = 0; j <n;j++){
if(b[j] !=0){
cout<<b[j]<< " ";
}
}
}
array will be filled with some value of " int random_number = rand() %1000000

Sample input output might help, but what is "if(b[j] !=0)" supposed to be doing here? I imagine print 0 when the count is 0 will give a more useful result.
edit: reading the code of the other answer.. it makes sense now, but his code is also missing a for loop lol.
void binsort(int arr[], int n){
int maxsize = 1000000;
int *b = new int[maxsize];
for( int i = 0; i <= maxsize;i++){
b[i] = 0;
}
for( int i = 0; i <n;i++)
{
b[arr[i]]++;
}
for(int j = 0; j <maxsize;j++){
if(b[j] !=0){
for (int k = 0; k < b[j]; k++){
cout<<j<< " ";
}
}
}

there are few issues in your code.
Here's the correct version
void binsort(int arr[], int n){
int maxsize = 1000000;
int *b = new int[maxsize];
for( int i = 0; i < maxsize;i++){ //correct the condition
b[i] = 0;
}
for( int i = 0; i <n;i++){
b[arr[i]]++;
}
for(int j = 0; j <maxsize;j++){ //run the loop for maxsize
if(b[j] !=0){
//Edit: loop over count to print the numbers
for(int k=0; k<b[j]; ++k) {
cout<<j<< " "; //print j not b[j]
}
}
}
}
Edit:
Forgot the case when there are duplicates in the array. Inner loop over 'count' takes care of it

Related

selection sort is not working properly it is not scanning the number which are at last of the array

#include<iostream>
using namespace std;
int main()
{
int arr[] = {40,20,14,20,55,14,22,45,22,447,441,224,421,2,14,1,9};
int size = sizeof(arr) / sizeof(int);
for (int i = 0; i < size; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
for (int i = 0; i < size; i++)
{
int Index_of_Min = i;
for (int j = i+1; j < size; j++)
{
if (arr[j] < arr[Index_of_Min])
{
Index_of_Min = j;
}
swap(arr[Index_of_Min], arr[i] );
}
}
for (int i = 0; i < size; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
return 0;
}
in the above program when we run it the number 9, 224 are not getting sorted
i want to understand why the program is not working anyone who knows the solution then your help is much appreciated
and please explain me what was my mistake so i will not repeat it again.
Thank You
Saw the exact same error only a few days ago. Your loop is wrong, specifically the swap is in the wrong place. This is how it should look
for (int i = 0; i < size; i++)
{
int Index_of_Min = i;
for (int j = i+1; j < size; j++)
{
if (arr[j] < arr[Index_of_Min])
{
Index_of_Min = j;
}
}
swap(arr[Index_of_Min], arr[i] );
}
You do the swap after the inner loop has found the index of the minimum element, not while it is finding that index.

Applying selection sort on an array of integers

int arr[] = {7,4,10,8,3,1};
int size = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i<size-1; i++){
int temp = arr[i];
for(int j = i+1; j < size; j++){
if(arr[j] < temp){
temp = arr[j];
}
}
swap(temp, arr[i]);
}
I am trying to apply the selection sort algorithm on the given array, but the output I am getting is only [1,1,1,1,1,1], I am finding the minimum element through the inner loop, Ican't figure out what is going wrong?
Slightly modified your code;
You need to pass reference(address) to both elements to take place of swapping contents
int arr[] = { 7, 1, 10, 8, 3, 11, 0, 12, 5, 8 };
int size = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i < size; i++)
{
auto temp = std::min_element( arr + i, arr + size );
std::swap( arr[i], *temp );
}
You have to add algorithm header to use std::min_element
int arr[] = {7,4,10,8,3,1};
int size = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i<size-1; i++){
int temp = arr[i];
int pos = i;
for(int j = i+1; j < size; j++){
if(arr[j] < temp){
temp = arr[j];
pos = j;
}
}
if(pos != i)
std::swap(arr[pos], arr[i]);
}
This should work.
It is suggested not to use using namespace std;. There is a plethora of reasons why you should not; that I will not mention.
By the way I tried to keep some of your variables the same but to be honest, I didn't. It is better to create variable names that explain what the code is doing. It makes your code a lot more legible and readable.
So opt out of one letter variables. It is fine in for loops, however this is a special case.
Now, here is another alternative suggested by #user4581301 & #Swift -Friday Pie. This method is using std::size using c++17.
For example:
#include <iostream>
#include <utility> // to use the swap() function.
#include <iterator> // to use std::size() function.
int main()
{
int arr[] = { 7,4,10,8,3,1 };
// This --> int size = sizeof(arr) / sizeof(arr[0]); is archaic.
const int length = static_cast<int>(std::size(arr)); // Call this something other than "size"; you can run into issues.
// We use static_cast<int> as a implicit conversion, and the obvious std::size(arr)).
// Going through the elements
for (int StartOfIndex = 0; StartOfIndex < length - 1; ++StartOfIndex)
{
// smallest is the index of the smallest element we’ve encountered this iteration
int smallest = StartOfIndex;
// Looking for a smaller element..
for (int current = StartOfIndex + 1; current < length; ++current)
{
// if we found an element smaller than our last; take note.
if (arr[current] < arr[smallest])
smallest = current;
}
// swap StartOfIndex with smallest.
std::swap(arr[StartOfIndex], arr[smallest]);
}
//Prints array.
for (int index = 0; index < length; ++index)
std::cout << arr[index] << " ";
std::cout << "\n";
return 0;
}
Output: 1 3 4 7 8 10
The first mistake you made in writing for loop's condition, don't use swap(temp, array[i]); yet try to get the basics first.
#include <iostream>
using namespace std;
int findsmall(int arr[], int i, int size){
int s, pos, j;
s = arr[i];
pos = i;
for(j = i+1; j < size; j++){
if(arr[j] < s){
s = arr[j];
pos = j;
}
}
return pos;
}
int main() {
int arr[] = {7,4,10,8,3,1};
int size = sizeof(arr) / sizeof(arr[0]);
int smallnum;
int temp;
int count = 0;
cout << "Original array: ";
for(int i = 0; i < size; i++){
if(i < size - 1){
cout << arr[i] << ", ";}
else{
cout << arr[i];
}
}
cout << endl;
for(int i = 0; i < size; i++){
smallnum = findsmall(arr,i, size);
temp = arr[i];
arr[i] = arr[smallnum];
arr[smallnum] = temp;
count++;
}
cout << "Sorted array: ";
for(int i = 0; i < size; i++){
if(i < size - 1){
cout << arr[i] << ", ";}
else{
cout << arr[i];
}
}
cout << endl;
return 0;
}
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int arr[], int n)
{
int i, j, min_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n-1; i++)
{
// Find the minimum element in unsorted array
min_idx = i;
for (j = i+1; j < n; j++)
if (arr[j] < arr[min_idx])
min_idx = j;
// Swap the found minimum element with the first element
swap(&arr[min_idx], &arr[i]);
}
}
selectionSort(arr,size);
This should work.

C++ why is there a segmentation fault in my pointer selection sort?

Below is my c++ code. I am trying to implement a selection sort using pointers (start and end). The code compiles, but I am getting a segmentation fault before it will sort the random generated list (currently only prints the random numbers).
Any help as to why this is and how to fix it would be greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;
void selectionSort(int *start, int *stop) {
for (int i = *start; i < *stop - 1; ++i) {
int min = i;
for (int j = i + 1; j < *stop; ++j) {
if ((&start[0])[j] < (&start[0])[min])
min = j;
}
swap((&start[0])[i], (&start[0])[min]);
}
}
int main()
{
int size = 10;
int* data = new int[size];
for (int i = 0; i < size; ++i)
{
data[i] = rand() % size;
}
for (int k = 0; k < size; k++)
{
cout << data[k] << " ";
}
cout << endl;
selectionSort(data, data+size);
for (int j = 0; j < size; j++)
{
cout << data[j+1] << " ";
}
return 0;
}
The general logic in your function is in the right direction. However, you seem to be confused between values of the elements of the array and the indexing used to access the elements of the array.
The line
for (int i = *start; i < *stop - 1; ++i)
shows the first signs of the confusion.
You are initializing i with the value of the first element of the array and incrementing the value in the subsequent iterations of the loop. That is not correct. Incrementing the value of the first element of the array does not make logical sense.
*stop causes undefined behavior since stop points to a place one past the last valid element.
You need to use int* i, int* j, and int* min to properly sort the elements. That also means updating almost the entire function accordingly. Here's an updated function that works for me.
void selectionSort(int *start, int *stop) {
for (int* i = start; i < (stop - 1); ++i) {
int* min = i;
for (int* j = i + 1; j < stop; ++j) {
if (*j < *min)
{
min = j;
}
}
swap(*i, *min);
}
}
Also, the following lines in main are not correct. You end up accessing the array using an out of bounds index.
for (int j = 0; j < size; j++)
{
cout << data[j+1] << " ";
}
Replace them by
for (int k = 0; k < size; k++)
{
cout << data[k] << " ";
}

Bucket sort with huge random numbers

I know Bucket sort is has a lot of examples everywhere, so I tried to implement this so it can take huge random numbers with no luck
void Bucket_sort(int arr[], int max){
const int maxsize = max;
int bucket_list = new int [maxsize+1];
int length = sozeof(bucket_list) / sizeof(bucket[0]);
for(int i = 0; i <max;i++){
bucket_list[i] = 0; //fill with zeros
}
for (unsigned int i = 0; i <length; i++){
bucket_list[arr[i]]++;
}
int position = 0;
for (unsigned int i = 0 i < length; i++){
for(int k = 0; k<bucket_list[i];k++){
arr[position++] = i;
}
}
}
int main() {
int max = 50000
int arr[max];
for (int i = 0; i < max; i++){
arr[i] = rand() % 50000;
}
cout<<"Here are the numbers before Bucker Sort"<<endl;
for (int j = 0; j < max; j++){
cout<<arr[j];
}
Bucket_sort(arr,max);
for (int k = 0; k<max; k++){
cout<<arr[k];
}
}
some how I can't get it working, it will just out put the same order (unsorted)
I did find some same questions as mine, but none of them helped, here is one
https://stackoverflow.com/questions/20037176/c-bucket-sort-putting-integers-into-buckets
This line:
bucket_list = 0; //fill with zeros
this is changing your pointer, not filling with zeros. You should use
bucket_list[i] = 0; //fill with zeros
Edit: There are a lot more compiler issues with your code. Once you have those sorted out, the calculation of length is still wrong. You can't use the sizeof dividing trick, because bucket_list isn't an array. Replace
int length = sozeof(bucket_list) / sizeof(bucket[0]);
with
int length = maxsize
or just don't use length at all (you already have maxsize).
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
void Bucket_sort(int arr[], int max){
int maxsize = max;
int *bucket_list = new int[maxsize+1];
// int length = sozeof(bucket_list) / sizeof(bucket[0]);
int length = maxsize;
for(int i = 0; i <max;i++){
bucket_list[i] = 0; //fill with zeros
}
for (unsigned int i = 0; i <length; i++){
bucket_list[arr[i]]++;
}
int position = 0;
for (unsigned int i = 0 ; i < length ; i++){
for(int k = 0; k<bucket_list[i];k++){
arr[position++] = i;
}
}
}
int main() {
int max = 50;
int arr[max];
for (int i = 0; i < max; i++){
arr[i] = rand()%50;
}
cout<<"Here are the numbers before Bucker Sort"<<endl;
for (int j = 0; j < max; j++){
cout<<arr[j];
}
Bucket_sort(arr,max);
for (int k = 0; k<max; k++){
cout<<arr[k];
}
getch();
return 0;
}

Selection sort ascending

That is my function:
int main() {
double data[100];
int num;
cout<<"num= ";
cin>>num;
for(int i = 1; i <= num; i++) {
cout<<i<<" element = ";
cin>>data[i];
}
Sort(data, num);
for (int i = 1; i <= num; i++) {
cout<<data[i]<<endl;
}
return 0;
}
void Sort(double data[], int n) {
int i,j,k;
double min;
for(i = 0; i < n-1; i++) {
k = i;
min = data[k];
for(j = i+1; j < n; j++)
if(data[j] < min) {
k = j;
min = data[k];
}
data[k] = data[i];
data[i] = min;
}
}
if I write for exp. three elements: 8,9,1 again cout 8,9,1?
for(int i = 1; i <= num; i++) { // WRONG
I think you mean:
for(int i = 0; i < num; i++) { // RIGHT
Arrays in C are 0-indexed remember.
Your sorting function is fine. The only problem is that you enter elements at positions 1 through n, inclusive, while you should use 0 through n-1, inclusive, in both loops of the main() function.
If you need to print numbers 1 through n, use
cout<<(i+1)<<" element = ";
You should get used of the 0 index begin in the for loop
for(int i = 0; i < N; ++i)
so fixing these two index errors will make your code run properly.
the reason is:
if you write data to data[] using 1 as the begining, your data array's first item will be a random number:
if you insert 3 elements, the array will be like this:
data[0] = ??? // maybe a very very big number
data[1] = 8
data[2] = 9
data[3] = 1
and in your Sort function, your index begins at 0 and ends before num, that means your code would only sort data[0], data[1], data[2].
if you use: num = 3, 3 2 1 as your input data for the origin code you could see that 3 and 2 is sorted
I guess your Sort code is googled from somewhere, please try to understand it.
Good online algorithm course: https://www.coursera.org/course/algs4partI
a very good algorithm online book: http://algs4.cs.princeton.edu/home/
btw, for(j = i+1; j < n; j++) in the Sort function would be better if it has { } braces.