Selection sort in C usually written in the form of the following code below, introducing a min_pos variable in which is stored the index of the minimum number of the array in a particular step of a for loop:
void selectionsort(int A[], int n)
{
for (int i = 0; i < n - 1; i++)
{
int min_pos = i;
for (int j = i + 1; j < n; j++)
{
if (A[j] < A[min_pos])
{
min_pos = j;
}
if (min_pos != i)
{
int temp;
temp = A[i];
A[i] = A[min_pos];
A[min_pos] = temp;
}
}
}
return;
}
But, Is it necessary to introduce this variable when we can get the same result using the following code?
void selectionsort(int A[], int n)
{
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (A[j] < A[i])
{
int temp;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}
return;
}
Both functions achieve the same result but neither one is a correct implementation of selection sort. They implement a less efficient algorithm called exchange sort.
For selection sort, a single swap should be performed for each element in the array. This was probably the purpose of the min_pos variable in the first function.
Here is a modified version:
void selectionsort(int A[], int n)
{
for (int i = 0; i < n - 1; i++)
{
int min_pos = i;
for (int j = i + 1; j < n; j++)
{
if (A[j] < A[min_pos])
{
min_pos = j;
}
}
if (min_pos != i)
{
int temp = A[i];
A[i] = A[min_pos];
A[min_pos] = temp;
}
}
}
Here's a wondeful explanation (unmodified) by owner of a youtube channel named : portfolio courses
Wow - this is an awesome question! :-) So the above algorithm will work too, but it just sorts the array in a different way. As to why we might not do it this way:
This is a video on selection sort, and the above algorithm is not selection sort (even though it's close to it). In selection sort we find the smallest/largest element in the unsorted portion and swap it with the leftmost unsorted algorithm. Other approaches may also work, but they will not be a selection sort anymore. The above approach will do many, many more swaps than required.
For comparison's sake, I modified this code here to test the two different algorithms: https://github.com/portfoliocourses/c-example-code/blob/main/selection_sort.c. I modified the code to count the number of swaps required (see the modifications below for Selection Sort and this New Algorithm you've made). Selection Sort required only 6 swaps, where as the code above required 31 swaps.
One of the reasons why Selection Sort is used is that it's helpful when the cost of performing a swap in terms of time is high: https://en.wikipedia.org/wiki/Sorting_algorithm#Selection_sort. I know it's Wikipedia, but see this quote: "It does no more than n swaps, and thus is useful where swapping is very expensive."
Selection Sort:
int num_swaps = 0;
for (int i = 0; i < length - 1; i++)
{
// find the position of the minimum element in the unsorted portion of
// the array
int min_pos = i;
for (int j = i + 1; j < length; j++)
if (a[j] > a[min_pos]) min_pos = j;
// if that element is NOT the element at index i, then swap that element
// with the element at index i
if (min_pos != i)
{
int temp = a[i];
a[i] = a[min_pos];
a[min_pos] = temp;
num_swaps++;
}
}
New Algorithm:
int num_swaps = 0;
for (int i=0; i<length-1; i++)
{
for (int j=i+1; j<length; j++)
{
if(a[i]>a[j])
{
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
num_swaps++;
}
}
}
I think both algorithms are not particularly efficient, a more efficient way to write them would be as below:
void selectionsort(int A[], int n)
{
for (int i = 0; i < n - 1; i++)
{
int min_pos = i;
for (int j = i + 1; j < n; j++)
{
if (A[j] < A[min_pos])
{
min_pos = j;
}
}
if (min_pos != i)
{
int temp;
temp = A[i];
A[i] = A[min_pos];
A[min_pos] = temp;
}
}
return;
}
Notice how the min_pos variable is used as a temporary storage for the swapping position. This is beneficial since the swapping requires three operations while using min_pos only requires one operation.
Related
How can you print the array per iteration in Bubble sort?
So far this is my sort function and im not really sure about it:
void sortBubble(int *arr)
{
int i, j;
int temp;
for (i = 0; i < SIZE; i++)
{
for (j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
printArr(arr); //call print function to print sorted array
}
If you want something to happen on each iteration of a loop, it should be placed within the loop body.
void sortBubble(int *arr)
{
int i, j;
int temp;
for (i = 0; i < SIZE; i++)
{
for (j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
printArr(arr);
}
}
It's also advisable to minimize the scope of variables. i, j, and temp do not need to be scoped at the function level.
void sortBubble(int *arr)
{
for (int i = 0; i < SIZE; i++)
{
for (int j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
printArr(arr);
}
}
One final note: you can optimize your bubble sort by keeping track of the number of swaps performed in the inner loop. If zero swaps are performed you know the array is already sorted and you can immediately return.
Bubble sort is O(n^2) in the worst case. Your implementation is always O(n^2). This small change can reduce it to O(n) in the best case scenario, or in the realistic scenario, somewhere in between.
void sortBubble(int *arr)
{
for (int i = 0; i < SIZE; i++)
{
int swaps = 0;
for (int j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
swaps++;
}
}
printArr(arr);
if (swaps == 0 /* or !swaps */) return;
}
}
Hi I'm using gdb to debug my bubble sort code but I don't get why it keeps breaking at if(a[j] < a[j-1]
here is my bubble sort function
void sort(int a[], int n) {
int i, j, nswaps, tmp;
for(i = 0; i < n; i++) {
nswaps = 0;
for(j = 0; j > i; j++) {
if(a[j] < a[j-1]) {
tmp = a[j];
a[j] = a[j-1];
a[j-1] = tmp;
nswaps++;
}
}
if(nswaps == 0) break;
}
}
Please do help me thanks!!
updated code: still has a segmentation fault
void sort(int a[], int n) {
int i, j, nswaps;
for (i = 0; i < n; i++) {
nswaps = 0;
for (j = 1; j > i; j++) {
if (a[j] < a[j-1]) {
int tmp;
tmp = a[j];
a[j] = a[j-1];
a[j-1] = tmp;
nswaps++;
}
}
if (nswaps == 0) break;
}
}
In the first iteration of the outer loop (when value of i is 0), the inner loop becomes an infinite loop, because value of j starts from 0 and keeps increasing. Eventually j becomes large enough for your program to access some unallocated memory, hence causing a segmentation fault.
Also, in the first iteration of the inner loop, value of j is 0, so a[j - 1] will try to access a memory location out of bound for your program.
j > i is false on the first iteration, so if(nswaps == 0) is true and the loops break, no sorting occurs.
Instead of iterating the outside loop n times, iterate n-1 times.
No need to count swaps, a simply boolean is sufficient.
After the first inner loop iteration, the lowest element of the array is found and in place at the end. The next inner loop only needs to iterate to next-last element, etc.
size_t is the Goldilocks type for array indexing, neither too narrow, nor too wide. Better than using int for indexing. Remember that is is an_unsigned type_.
No need to declare a variable until needed.
#include <stdbool.h>
#include <stdlib.h>
void bubble_sort(int a[], size_t n) {
while (n > 1) {
bool swapped = false;
for (size_t j = 1; j < n; j++) {
if (a[j-1] < a[j]) {
int tmp = a[j];
a[j] = a[j - 1];
a[j - 1] = tmp;
swapped = true;
}
}
if (!swapped) {
break;
}
n--;
}
}
Let's say I have a sort function for 1D array
void sort(int a[], int n){
int temp;
for (int i = 0; i < n; i++){
for (int j = i + 1; j < n; j++){
if (a[i] > a[j]){
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
}
I know how to make it sort all rows of 2D array:
for (i = 0; i < n; i++)
sort(b[i], m); // b is 2d array n - rows m - columns
But I'm wondering what do I have to change, to be able to use the same function to sort columns instead?
You can modify the sort function to traverse through columns by passing an extra argument:
void sort(int a[n][m], int n, int col_index){
int temp;
for (int i = 0; i < n; i++){
for (int j = i + 1; j < n; j++){
if (a[i][col_index] > a[j][col_index]){
temp = a[j][col_index];
a[j][col_index] = a[i][col_index];
a[i][col_index] = temp;
}
}
}
}
And then implement as follows
for(int i=0;i<m;i++){
sort(b,n,i);
}
Hope this helps.
You can transpose the incoming 2D array to exchange rows and columns and do the normal sorting.
maybe add a flag to determine if you need to do transpose or not
Looking for help describing this Algorithm for sorting an array. Is it a bubble or selection sort? Why do the elements switch?
#include <stdio.h> //including stdio.h for printf and other functions
#include <conio.h> //including conio.h for _getch() and other functions
int main() //default function for call
{
int a[10] = { 2,4,6,8 }; //Array declaration size-10
int n = 4; //Temporary number for array size
printf("\n\nArray Data : ");
flushall(); //Printing message
for (int i = 0; i < n; i++) //Loop for displaying the data of array
{
printf(" %d ", a[i]); //Printing data
}
for (int i = 0; i < n; i++) //Loop for ascending ordering
{
for (int j = 0; j < n; j++) //Loop for comparing other values
{
if (a[j] > a[i]) //Comparing other array elements
{
int tmp = a[i]; //Using temporary variable for storing last value
a[i] = a[j]; //replacing value
a[j] = tmp; //storing last value
}
}
}
}
This is a less efficient way of bubble sort.
You can find explanations here :
https://en.wikipedia.org/wiki/Bubble_sort#Step-by-step_example
A better code will be
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
{
// swap temp and arr[i]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
It reduces number of comparisons and looping by optimizing the upper limit of loops.
You can see a video on this here.
I need to know a method to keep duplicate numbers from being stored in a new array when taking numbers from two different arrays. The function is supposed to store each 'unique' value once and not store duplicate values again.
Here is my function code so far:
int * arrayIntersect(int *sizeOfResult, const int *a, const int *b, int sizeOfA, int sizeOfB){
int i;
int j;
int k = 0;
int c[(sizeOfA + sizeOfB)];
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < sizeOfA; i++){
if(a[i] == b[j]){
c[k] = a[i];
(*sizeOfResult)++;
k++;
}
}
}
int *d = (int *)malloc(sizeof(int) * *sizeOfResult);
for(i = 0; i < *sizeOfResult; i++){
d[i] = c[i];
}
return d;
}
It prints the values I need, but I want to eliminate the same number from showing up multiple times when printing the contents of the new dynamic array.
Any idea on how to improve my code to allow prevent duplication?
The proper way to do it is having the arrays ordered and then doing a binary search for each insertion like #Murilo Vasoncelos pointed out.
Below is a quick and dirty solution that loops through a and b and for each iteration checks if the number has been inserted before. If it isn't, it inserts it.
int duplicate = 0;
*sizeOfResult = 0;
for(j = 0; j < sizeOfA; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == a[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = a[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == b[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = b[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
If your arrays a and b are ordered, you can simply use this linear algorithm for array intersection:
int* inter(int* szr, int* a, int* b, int sza, int szb)
{
int c[MAX(sza, szb)];
int i, j, k = 0;
for (i = 0, j = 0; i < sza && j < szb;) {
if (a[i] == b[j]) {
if (k == 0 || c[k - 1] < a[i]) {
c[k++] = a[i];
}
i++;
j++;
}
else if (a[i] < b[j]) {
i++;
}
else {
j++;
}
}
*szr = k;
int* ans = (int*)malloc(sizeof(int) * k);
for (i = 0; i < k; ++i) {
ans[i] = c[i];
}
return ans;
}