Insertion sorts's problamatic area - c

for(i = 1; i < len; i++){
for(j = i - 1; j >= 0; --j){
if(data[j] > data[1 + j]){
swap(j, j + 1);
} else {
break;
}
}
}
swap method does swapping elements. Why it should be --j instead of j-- ? what is the difference ? what is the advantage of putting j-- ?

In this context both work.
In C++ there are good reasons to use ++i.
Since you're coding in C choose one and stick with it.

For primite types there is no performance difference between postfix and prefix increment/decrement.
By the way there is more efficient insertion sort algo implementation, only 1 assignment in inner loop (swap performs 3).
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i-1;
for (j = i-1; j >= 0 && arr[j] > key; --j) {
arr[j+1] = arr[j];
}
arr[j+1] = key;
}

Related

Why do I get a random number in the first element of the sorted array?

I am new to C and when I do this which makes the elements in the list arranged:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int list[] = {6, 4, 8, 1, 0, 9, 11, 50, 60, 10};
int i, j, aux, k;
int len = sizeof(list) / sizeof(list[0]);
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
if (list[j] > list[j + 1])
{
aux = list[j + 1];
list[j + 1] = list[j];
list[j] = aux;
}
}
}
for (k = 0; k < len; k++)
{
printf("%d ", list[k]);
}
return 0;
}
Output :
-13168 0 1 4 6 8 9 10 11 50
Why is the first value -13168?
Both your i and your j walk all the range of legal indices in the array.
But you do access list[j+1] which is one beyond the array, read there and sort the value you get from there.
As said list[j + 1] steps out of the bounds of the array, and as said using for (j = 0; j < len - 1; j++) will solve the issue.
However, as it is, the second loop will always go through the entire array and that is not needed, as the values are swapped i will be incremented and the number of needded iterations will become lesser , so you can use i iterator in the stop condition of the second loop thus optimizing it by reducing the number of iterations.
for (i = 0; i < len - 1; i++) //len - 1 is enough
{
for (j = 0; j < len - i - 1; j++) //replacing < len with < len - i - 1
{
if (list[j] > list[j + 1])
{
aux = list[j + 1];
list[j + 1] = list[j];
list[j] = aux;
}
}
}
Live demo
This is a more appropriate bubble sort.
Even for such a small array the difference in performance is noticeable, but there is still room for improvement.
When a swap no longer occurs in the loop it means that the array is sorted, so if we were to add a flag to stop ordering when this happens then you would have a very well optimized bubble sort algorithm:
int ordered = 0;
//...
for (i = 0; i < len - 1; i++)
{
ordered = 0; //reset flag
for (j = 0; j < len - i - 1; j++)
{
if (list[j] > list[j + 1])
{
aux = list[j + 1];
list[j + 1] = list[j];
list[j] = aux;
ordered = 1; //if the swap occurs, the ordering continues
}
}
if (ordered == 0) //otherwise the array is ordered and the ordering ends
break;
}
Live demo
As you can see by the testing this is a very fast bubble sort.
Benchmark results:
Your outer loop is useless. You never use i. I think you wanted:
for(i=0;i<len;i++){
for(j=0;j<i;j++){
if(list[j] > list[i]){
aux = list[i];
list[i] = list[j];
list[j] = aux;
}
}
}
When you are accessing list[j+1], you are out of bound in last iteration .
So, change inner loop to :
for(j=0;j<len-1;j++){ }
There is an error in the second loop:
for(j = 0; j < len; j++)
should be
for(j = 0; j < len - 1; j++)

Bubble-Sort not sorting in C (Cormen's pseudocode)

So I was trying to implement Cormen's pseudocode for bubble sorting but I can't seem to get it to work.
This is my approach on Cormen's pseudocode:
void BUBBLE_SORT(int a[200], int n) {
int i, j, aux;
for (i = 1; i <= n - 1; i++) {
for (j = n; j < i + 1; j++) {
if (a[j] < a[j - 1]) {
aux = a[j];
a[j] = a[j + 1];
a[j + 1] = aux;
}
}
}
}
I tried another piece of code found on the internet but the result was not different:
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n - 1; i++)
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(&arr[j], &arr[j + 1]);
}
I would love to know where my comprehension failed in understanding Cormen's implementation and to get the bubble sorting to work!
There are at least three issues:
The pseudocode assumes array indices go from 1 to length. In C arrays are indexed from 0 to length-1; your code doesn't correct for that.
The inner loop in the pseudocode goes downto i+1, but your inner loop tries to count up:
for(j=n;j<i+1;j++)
should be
for (j = n; j > i; j--)
The pseudocode swaps A[j] and A[j-1], but your C code swaps A[j] and A[j+1].
Mistakes in your implementation:
You start counting your array from 1th index. But in C programing a array start with 0th position. [you should right i = 0 instead of i = 1]
The inner loop must run from j = n-1 from j = i+1 and the value of j must be decreasing.
You compare a[j] with a[j-1] but u swap a[j] with a[j+1]. you should have swap a[j] with a[j-1]
See the changes in the code below. Hope it will be useful:
int i, j, aux;
for(i=0;i<n-1;i++){
for(j=n-1;j>=i+1;j--){
if(a[j]<a[j-1]){
aux=a[j];
a[j]=a[j-1];
a[j-1]=aux;
}
}
}

C - Insertion Sort Algorithm

I'm trying to sort a set of numbers like this:
A[]={3,6,7,2,9,1,2,7,2}
A[]={3,6,7,2,2,2,9,1,7}
So I've made this:
void sort_min(int* point, int size_array, int min_n){
int i = 0;
int j = 0;
int k = 0;
while(point[i] != min_n){
i++;
}
j = i+1;
while(point[j] != min_n){
j++;
}
k = j;
for (j-1; j > i; j--){
point[j] = point[j-1];
}
point[j] = min_n;
j = k+1;
}
Like you can notice I've never used the int size_array cause I don't know the way to match an iterative function like a for or a while (That's the question. How to solve it?). I've done that, of course, but I've got a Segmentation fault like an answer.
The main concept is looking for a number int min_n and up to that point sort that number at each occurrence in the array.
Thanks for all.
You need use size_array like below, if you are asking about this.
You need compare i and j with size_array in while.
while (i < size_array && point[i] != min_n) {
i++
}
Need check value of i, j after while. They may be larger or equal to size_array.
while (i < size_array && point[i] != min_n) {
i++
}
// I guess when you don't find min_n, function can just return.
if (i >= size_array)
return;
j = i+1;
while(j < size_array && point[j] != min_n){ // Also need check j's value.
j++;
}
// Also guess when can't find the second min_n position, function can return.
if (j >= size_array)
return;
k = j
for (; j > i; j--) // No need j-1.
point[j] = point[j-1];
// This is useless. When code come here, j == i and point[i] == min_n;
point[j] = min_n;
j = k+1;
Try the Insertion Sort with the code as follows..
void sort_min(int point[], int size_array)
{
int i, key, j;
for (i = 1; i < size_array; i++)
{
key = point[i];
j = i-1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && point[j] > key)
{
point[j+1] = point[j];
j = j-1;
}
point[j+1] = key;
}
}

Can't Count - Number of Comparison Operations

So I have this segment of code that was given to me.
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++)
{
if (arr[j] < arr[i])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
I am trying to calculate the number of comparison operations that would occur if the code were to run.
There's the initial comparison all the way up to i=100. so there's 101 comparisons for the outer loop. The inner loop also has 101 loops, but that comparison within will only happen 100 times due to the j=100 will not have that comparison occurring.
I've made a tries but none of been the right answer so far.
I've had 101 x (101+100) = 20301 which is not the right answer.
I've searched for this on google and came up with a question identical to this but was answering how many assignment operations that occur which I was able to answer on my own. Which btw is 25201.
I got 20201.
#include <stdio.h>
int main(void) {
int i, j;
unsigned long count;
count = 0;
for (i = 0; ++count, i < 100; ++i) {
for (j = 0; ++count, j < 100; ++j) {
++count;
}
}
(void) printf("%lu\n", count);
return 0;
}
100 comparisons on the outer loop drive 101 + 100 comparisons on the inner loop. There is one more comparison on the outer loop to detect loop termination, so:
100 * (101 + 100) + 101 = 20201.
Instrumenting the program:
outer_cmps=0;
total_inner_cmps=0;
for (int i = 0; i < 100; i++) {
++outer_cmps;
inner_cmps=0;
for (int j = 0; j < 100; j++)
{
++inner_cmps;
if (arr[j] < arr[i])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
++inner_cmps;
}
++inner_cmps;
tota_inner_cmps += inner_cmps;
}
++outer_cmps;
total_cmps = outer_cmps + total_inner_cmps;
So that would be 100*200+100+1=20101
(100 times i, which runs the j loop 100 times, which performs 1 comparisson if (arr[j] < arr[i]) per loop, and one i loop that fails when i==100and 100 times j loop that fail when j==100)

What is Innermost loop in imperfectly nested loops?

Helo, I'm a bit confused about the definition of an inner loop in the case of imperfectly nested loops. Consider this code
for (i = 0; i < n; ++i)
{
for (j = 0; j <= i - 1; ++j)
/*some statement*/
p[i] = 1.0 / sqrt (x);
for (j = i + 1; j < n; ++j)
{
x = a[i][j];
for (k = 0; k <= i - 1; ++k)
/*some statement*/
a[j][i] = x * p[i];
}
}
Here, we have two loops in the same nesting level. But, in the second loop which iterates over "j" starting from j+1, there is a again another nesting level. Considering the entire loop structure, which is the inner most loop in the code ?
Both j loops are nested inside i equally, k is the inner most loop
Lol I don't know how to explain this so i'll give it my best shot I recommend using a debugger! it may help you so much you won't even know
for (i = 0; i < n; ++i)
{
//Goes in here first.. i = 0..
for (j = 0; j <= i - 1; ++j) {
//Goes here second..
//Goes inside here and gets stuck until j is greater then (i- 1) (right now i = 0)
//So (i-1) = -1 so it does this only once.
/*some statement*/
p[i] = 1.0 / sqrt (x);
}
for (j = i + 1; j < n; ++j)
{
//Goes sixth here.. etc.. ..
//when this is done.. goes to loop for (i = 0; i < n; ++i)
//Goes here third and gets stuck
//j = i which is 0 + 1.. so, j == 1
//keeps looping inside this loop until j is greater then n.. idk what is n..
//Can stay here until it hits n.. which could be a while.
x = a[i][j];
for (k = 0; k <= i - 1; ++k) {
//Goes in here fourth until k > (i-1).. i is still 0..
//So (i-1) = -1 so it does this only once
/*some statement*/
a[j][i] = x * p[i];
}
//Goes here fifth.. which goes.... to this same loop!
}
}
I'd say that k is the inner-most loop, because if you count the number of loops required to reach it from the outside, it's three loops, and that's the most out of all four of the loops in your code.

Resources