I have written a C-program to generate random numbers and then sort them with the bubblesort-algorithm.
However, printing out the numbers (by an array, see the code) will show that the first element is 63, no matter what the randomly generated numbers were.
What causes this? And is there a more elegant way to bypass this than just skipping the first element of the list?
int list[10];
int cache_num;
srand((unsigned) (time(NULL))); //Gives the rand() function a new seed from the current time
for (int i = 0; i < 10; i++) {
list[i] = rand();
printf("\n%d", list[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < (10 - i); j++) {
if (list[j] > list[j + 1]) {
cache_num = list[j];
list[j] = list[j + 1];
list[j + 1] = cache_num;
}
}
}
for (int i = 0; i < 10; i++) {
printf("\n%d", list[i]);
}
In the inner loop of these loops
for (int i = 0; i < 10; i++) {
for (int j = 0; j < (10 - i); j++) {
if (list[j] > list[j + 1]) {
cache_num = list[j];
list[j] = list[j + 1];
list[j + 1] = cache_num;
}
}
}
there is an access to the non-existent element of the array with the index 10
list[j] = list[j + 1];
^^^^^^
when j is equal to 9.
It si better to write the loop like
for (int j = 1; j < (10 - i); j++) {
if (list[j - 1] > list[j]) {
cache_num = list[j];
list[j] = list[j - 1];
list[j - 1] = cache_num;
}
You are going one past the array when the variable j reaches the value of 9. Use (10 - i - 1) to resolve the issue:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int list[10];
int cache_num;
srand((unsigned) (time(NULL))); //Gives the rand() function a new seed from the current time
for (int i = 0; i < 10; i++) {
list[i] = rand();
printf("%d\n", list[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < (10 - i - 1); j++) { // note here ...
if (list[j] > list[j + 1]) {
cache_num = list[j];
list[j] = list[j + 1];
list[j + 1] = cache_num;
}
}
}
putchar('\n');
for (int i = 0; i < 10; i++) {
printf("%d\n", list[i]);
}
return 0;
}
Here in the following line you are going out of bounds because of which your are getting garbage value and thus altering your final result. Ex: when i=0 and j=9, this loops terminating condition will be is 9 < 10-0 which is true and it will execute. But for list [ j + 1 ] it will go out of bounds because there is no list [ 10 ].
for (int j = 0; j < (10 - i); j++){ ... }
It should have condition with -1 , (10-i-1)
for (int j = 0; j < (10 - i - 1); j++) { ... }
Instead of your implementation of the bubble sort to sort the data of 10 elements, you can use the below implementation.
The idea behind is that when you analyze (which you should) how the bubble-sort algorithm basically sorts the data, you will see a pattern i.e. in each pass of the inner-loop, the largest element (in-case of sorting the data in increasing order) will automatically go to its right location so, you don't need to consider that element again as it is already in its right position.
#include <stdio.h> // For basic I/O functions.
#include <stdlib.h> // For srand() & rand() functions.
#include <time.h> // For time(NULL) functions.
#define MAX_ARRAY_SIZE 10
int main(void) {
int list[10];
srand(time(NULL));
for(int i = 0; i < MAX_ARRAY_SIZE; ++i) {
list[i] = rand();
}
// Implementation of Bubble-Sort
for(int i = (MAX_ARRAY_SIZE - 1); i >=0; --i) {
bool is_sorted = true;
for(int j = 0; j < i; ++j) {
if(list[j] > list[j + 1]) {
int cache_num = list[j];
list[j] = list[j + 1];
list[j + 1] = cache_num;
is_sorted = false;
}
}
if(is_sorted) {
break;
}
}
for(int i = 0; i < MAX_ARRAY_SIZE; ++i) {
printf("%d ", list[i]);
}
printf("\n");
return 0;
}
P.S: As you are sorting only 10 elements, using bubble-sort is not going to make any difference, but I suggest you use insertion-sort instead of bubble-sort because insertion-sort is faster for small-size arrays.
Refer: Comparison Between Bubble-Sort/Selection-Sort/Insertion-Sort.
For Some Fun: Watch this bubble sort algorithm dance. 😁
Related
I was trying to implement bubble sort algorithm to sort a 10 element array. I've tried writing the code below and it doesn't seem wrong, but it doesn't sort the elements at all.
Could someone give me a hand?
This is the code:
`
#include <stdio.h>
#define DIM 10
int main() {
int arr[DIM] = {1, 5, 6, 8, 7, 9, 3, 2, 4, 10};
int tmp;
puts("Original array: ");
for (int i = 0; i < DIM; i++) {
printf("%3d", arr[i]);
}
// Bubble sort
for (int i = 0; i < DIM - 1; ++i) {
for (int j = 0; j < DIM - i - 1; ++j) {
// Compare two elements and swap if first > second
// Use of tmp variable (temporary)
if (arr[i] > arr[i + 1]) {
tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
}
}
}
puts("");
puts("Ascending order arrray: ");
for (int i = 0; i < DIM; i++) {
printf("%3d", arr[i]);
}
puts("");
}
`
In the second loop, j should be used instead of i
if (arr[j] > arr[j + 1]) {
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
Use j in the body of the second loop instead of i.`
// Bubble sort
for (int i = 0; i < DIM - 1; ++i) {
for (int j = 0; j < DIM - i - 1; ++j) {
// Compare two elements and swap if first > second
// Use of tmp variable (temporary)
if (arr[j] > arr[j + 1]) {
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
#include <stdio.h>
#define DIM 10
int main() {
int arr[DIM] = {1, 5, 6, 8, 7, 9, 3, 2, 4, 10};
int tmp;
puts("Original array: ");
for (int i = 0; i < DIM; i++) {
printf("%3d", arr[i]);
}
// Bubble sort
for (int i = 0; i < DIM - 1; ++i) {
for (int j = 0; j < DIM - i - 1; ++j) {
// Compare two elements and swap if first > second
// Use of tmp variable (temporary)
if (arr[j] > arr[j + 1]) {
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
puts("");
puts("Ascending order arrray: ");
for (int i = 0; i < DIM; i++) {
printf("%d", arr[i]);
}
puts("");
}
*Change: need to use "j" inplace of "i" in the 2nd for loop statements.
I want to randomize a to p without repetition.
int main(){
int array2[4][4];
bool arr[100]={0};
int i;
int j;
srand(time(NULL));
for(i=0; i<=3; i++){
for(j=0; j<=3; j++){
int randomNumber1;
randomNumber1 = (rand() % (82-65+1))+65;
if (!arr[randomNumber1])
{
printf("%c ",randomNumber1);
array2[i][j]=randomNumber1;
}
else
{
i--;
j--;
arr[randomNumber1]=1;
}
}
printf("\n");
}
return;
the output still has repeat alphabet. I want to have the output in 4x4 with with all a to p without it repeating.
There are some errors in your code. IMHO the most serious is that arr[randomNumber1]=1; is is the wrong branch of the test. That means that your current code does not invalidate once a number was used but only if it has already been invalidated => if you control the arr array at the end of the program all value are still 0.
That is not all. When you get a duplicate, you should only reset the inner loop, and you are currently off by 2 in your maximum ascii code: you go up to R when you want to stop at P.
Your code should be:
for (i = 0; i <= 3; i++) {
for (j = 0; j <= 3; j++) {
int randomNumber1;
randomNumber1 = (rand() % (81 - 65)) + 65;
if (!arr[randomNumber1])
{
printf("%c ", randomNumber1);
array2[i][j] = randomNumber1;
arr[randomNumber1] = 1;
}
else
{
//i--;
j--;
}
}
printf("\n");
}
But this kind of code is terribly inefficient. In my tests it took 30 to 60 steps to fill 16 values, because random can return duplicates. This is the reason why you were advised in comments to use instead the modern algorithm for Fisher-Yates shuffle:
int main() {
int array2[16];
unsigned i, j, k=0;
// initialize array with alphabets from A to P
for (i = 0; i < sizeof(array2); i++) {
array2[i] = 'A' + i;
}
// Use Fisher-Yates shuffle on the array
srand(time(NULL));
for (i = 15; i > 0; i--) {
j = rand() % (i + 1);
if (j != i) {
int c = array2[i];
array2[i] = array2[j];
array2[j] = c;
}
}
// Display a 4x4 pattern
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
printf("%c ", array2[k++]);
}
printf("\n");
}
return 0;
}
Which shuffles the array in only 16 steps.
Here is the outline
// Need some #includes here - exercise for the reader
char items[] = "abcdefghijklmnopqrstuvwxyz";
int len = sizeof(items);
srand(time(NULL));
while (len > 0) {
int r = rand() % len;
printf("%c", items[r]);
len--;
items[r] = items[len];
}
This should do the trick to print the whole alphabet in random order without repeats. Modify to do what you need it to do
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define MAX 10
int main() {
int data[10], no, i, j, n, c;
printf("\n Enter no of elements :");
scanf("%d", &no);
printf("\nEnter the data");
for (i = 0; i < no; i++) {
scanf("%d", &data[i]);
}
n = MAX;
do {
for (i = 0; i < n - 1; i++) {
if (data[i] > data[i + 1]) {
data[i] = data[i] + data[i + 1];
data[i + 1] = data[i] - data[i + 1];
data[i] = data[i] - data[i + 1];
}
}
n = n - 1;
for (i = MAX - 1, c = 0; i >= c; i--) {
if (data[i] < data[i - 1]) {
data[i] = data[i] + data[i - 1];
data[i - 1] = data[i] - data[i - 1];
data[i] = data[i] - data[i - 1];
}
}
c = c + 1;
} while (n != 0 && c != 0);
printf("The sorted array is:");
for (i = 0; i < no; i++) {
printf("%d\t", data[i]);
}
}
I was confident it was bubble sort at first glance, until I saw the second looping – which confused me. Why would it sort from behind as well?
Could anyone tell me if it's a Bubble Sort or another type of sort?
#include<stdio.h>
int main(void)
{
int array[10] = { 10,2,9,4,5,6,7,8,3,1 };
/*Implementing Bubble Sort */
int temp;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 10 - i; j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
for (int i = 0; i < 10; i++)
{
printf("%d ", array[i]);
}
}
When I try to run the program I'm getting values sorted but one value has some garbage value and the dialogue box appears that stack around variable is corrupted in VS 2019. In some other compiler I'm getting 0 in place of 10 in compiler.
The inner for .loop
for (int j = 0; j < 10 - i; j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
invokes undefined behavior because when j is equal to 9 for the first iteration of the outer loop that is when i is equal to 0 the index in the expression array[j + 1] can be equal to 10 that results in accessing the memory beyond the array.
Rewrite the loop like
for (int j = 1; j < 10 - i; j++)
{
if (array[j-1] > array[j])
{
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}
}
You can you this logic slightly edited from yours.
#include<stdio.h>
int main(void)
{
int array[10] = { 10,2,9,4,5,6,7,8,3,1 };
/*Implementing Bubble Sort */
int temp;
for (int i = 0; i < 10; i++)
{
for (int j = i; j < 10; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
for (int i = 0; i < 10; i++)
{
printf("%d ", array[i]);
}
}
I'm coding a function in C to check if an array has any duplicate value, and if so replace it by any of the non-present ones. The array consists of numbers shuffled from 1 to Nmax:
unsigned char * NotRepeated (unsigned char *arr){
unsigned char i, j, count, k, notrepeated[Nmax];
k = 0;
for (i = 0; i < Nmax ; i++){
count = 0;
for (j = 0; j < Nmax; j++){
if (arr[j] != i + 1){
count++;
}
if (count == Nmax){
notrepeated[k] = i + 1;
k++;
}
}
}
k = 0;
for (i = 0; i < Nmax - 1; i++){
for (j = i + 1; j < Nmax; j++){
if (arr[i] == arr[j]){
arr[j] = notrepeated[k];
k++;
}
}
}
return arr
}
If I print the array notrepeated[k] I get almost all the array filled when the original array arr[j] seldomly has more than 2 repeated figures.
What am I doing wrong?
Thanks!