Bubble sort concept - c

I just want the explanation about the condition in nested for loop.
How its processing, i am bit confused. I want the logic behind the conditions of two for loops.
#include<stdio.h>
void bubblesort(int a[25],int n);
int main()
{
int a[25],size,i;
printf("Enter the size of an array");
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
}
bubblesort(a,size);
for(i=0;i<size;i++)
{
printf("%d\t",a[i]);
}
return 0;
}
void bubblesort(int a[], int n)
{
int temp,i,j;
for(i=0;i<n;i++)
{
for(j=0;j<(n-i)-1;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]= temp;
}
}
}
}

Bubble sort is a commonly used algorithm for sorting an array of integers. It's called "bubble sort" since it causes the largest values to "bubble" up to the end of the array.
Bubble sort moves one index at a time up the array essentially pulling the largest value along. For example, If the array is [1,3,2] bubble sort will check the 1 and see if it is greater than the value ahead of it: 3. It isn't so the one will stay in its place. Now the 3 is the largest value the program has seen so it will compare it to the next value, the 2. Is 3 bigger? Yes! So it will switch the 3 and the 2. Now the largest value is at the end of the array so the algorithm starts at the beginning of the array again. This repeats until the entire array is sorted.
On to the specifics:
The first for-loop for(i=0;i<n;i++) loops for the same amount of times as the size of the array, i.e. if the size is 7, this loops will execute 7 times. It does this because, in the worst case scenario, every value in the array will need to change location.
The inner-most for-loop for(j=0;j<(n-i)-1;j++) first of all has j never reaching the very last array spot, even when i = 0. This is because the code inside the loop, if(a[j]>a[j+1]), is always checking one value AHEAD of the current index. So, j must never equal the last value of the index because there will be an out of bounds error.
You will also notice that the inner-more for-loop goes from 0 to n-i-1. The reason this -i is included is because every time the outer loop, if(a[j]>a[j+1])`, is executed, one value will have moved all the way up to the end of the array. So you don't need to check the very last spot in the array because it's already correct!
Summary:
Bubble sort continually moves the largest value to the end of the list. It does this by constantly checking values as it moves up the list and moving the largest value up one step at a time.
Edit: See Cool Guy's comment for a link to a great visual representation of bubble sort.

Related

C: I made a program to sort an array in ascending order and cannot figure the reason for a certain step in the for loops

I am making a program to sort numbers in an array using the bubble sort method in c and I know how to do it but I cannot figure out what the second for loop's j<n-i-1subtraction of i from the length of the array is for. It is probably a simple explanation but I cannot for the life of me scramble my small brain for the answer.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int input[10],swap;
printf("Input Numbers: ");
scanf("%d%d%d%d%d%d%d%d%d%d",&input[0],&input[1],&input[2],&input[3],&input[4],&input[5],&input[6],&input[7],&input[8],&input[9]);
int n=10;
for(int i=0;i<n-1;i++){
for(int j=0;j<n-i-1;j++){
if(input[j]>input[j+1]){
swap=input[j];
input[j]=input[j+1];
input[j+1]=swap;
}
}
}
printf("Sorted List: {");
for(int i=0;i<10;i++){
if(i<9){
printf("%d, ",input[i]);
}
else{
printf("%d}",input[i]);
}
}
return 0;
}
In the first iteration of the i loop, the greatest element is bubbled to the end of the n elements in the array. After that, we know the last element is done. So we only need to do the n-1 remaining elements.
In the second iteration of the i loop, the next greatest element is bubbled to the end of the n-1 elements we were working on. After that, we know the last two elements are done. So we only need to do the n-2 remaining elements.
This continues, so that in each iteration, we only need to work on n-i elements. Since elements j and j+1 are compared, we only need j to reach n-i-2, i.e., be less than n-i-1., as that will give j+1 up to n-i-1. (The number of elements from index 0 to index n-i-1 is n-i.)

Delete duplicate in an array and insert first occurrence in a new array in C

I have to do a function which, taken as parameters a pointer (int *vect) and the dimension (dim) of the array allocated, returns a new array which contains all the elements of the old array not repeated and all the first occurrence of repeated elements, this is the code where i put the elements not repeated of the first array, but i don't know how to proceed to put the first occurrence of repeated elements (e.g. INPUT : vect={1;2;3;3;4;5;5} OUTPUT : {1;2;3;4;5})
int* deleteDup(int *vect,int dim){
int* vect2,int dim2;
vect2=malloc(sizeof(int)*dim2);
int i,j,temp;
int count=0;
for(i=0;i<dim-1;i++){
temp=vect[i];
for(j=i+1;j<dim;j++){
if(temp==vect[j]){
count++;
}
}
if(count==0){
dim2++;
vect2=realloc(vect2,dim2*sizeof(int));
vect2[dim2]=temp;
}
*dim_nodup=dim2;
return vect2;
}
This looks like homework to me.
You need to first count the number of unique elements, then allocate an array of that size, and then move one instance of each unique element to the new array.
This can be optimised various ways.
I prefer not to give you code or even pseudo code, as you should figure this out yourself when solving the problem.
i don't know how to proceed to put the first occurrence of repeated elements
To do this you must move elements one by one into the array you are returning, and for each item check if it is already in the array.
Good luck! :)

find the largest ten numbers in an array in C

I have an array of int (the length of the array can go from 11 to 500) and i need to extract, in another array, the largest ten numbers.
So, my starting code could be this:
arrayNumbers[n]; //array in input with numbers, 11<n<500
int arrayMax[10];
for (int i=0; i<n; i++){
if(arrayNumbers[i] ....
//here, i need the code to save current int in arrayMax correctly
}
//at the end of cycle, i want to have in arrayMax, the ten largest numbers (they haven't to be ordered)
What's the best efficient way to do this in C?
Study maxheap. Maintain a heap of size 10 and ignore all spilling elements. If you face a difficulty please ask.
EDIT:
If number of elements are less than 20, find n-10 smallest elements and rest if the numbers are top 10 numbers.
Visualize a heap here
EDIT2: Based on comment from Sleepy head, I searched and found this (I have not tested). You can find kth largest element (10 in this case) in )(n) time. Now in O(n) time, you can find first 10 elements which are greater than or equal to this kth largest number. Final complexity is linear.
Here is a algo which solves in linear time:
Use the selection algorithm, which effectively find the k-th element in a un-sorted array in linear time. You can either use a variant of quick sort or more robust algorithms.
Get the top k using the pivot got in step 1.
This is my idea:
insert first 10 elements of your arrayNum into arrMax.
Sort those 10 elements arrMax[0] = min , arrMax[9] = max.
then check the remaining elements one by one and insert every possible candidate into it's right position as follow (draft):
int k, r, p;
for (int k = 10; k < n; k++)
{
r = 0;
while(1)
{
if (arrMax[r] > arrNum[k]) break; // position to insert new comer
else if (r == 10) break; // don't exceed length of arrMax
else r++; // iteration
}
if (r != 0) // no need to insert number smaller than all members
{
for (p=0; p<r-1; p++) arrMax[p]=arrMax[p+1]; // shift arrMax to make space for new comer
arrMax[r-1] = arrNum[k]; // insert new comer at it's position
}
} // done!
Sort the array and insert Max 10 elements in another array
you can use the "select" algorithm which finds you the i-th largest number (you can put any number you like instead of i) and then iterate over the array and find the numbers that are bigger than i. in your case i=10 of course..
The following example can help you. it arranges the biggest 10 elements of the original array into arrMax assuming you have all positive numbers in the original array arrNum. Based on this you can work for negative numbers also by initializing all elements of the arrMax with possible smallest number.
Anyway, using a heap of 10 elements is a better solution rather than this one.
void main()
{
int arrNum[500]={1,2,3,21,34,4,5,6,7,87,8,9,10,11,12,13,14,15,16,17,18,19,20};
int arrMax[10]={0};
int i,cur,j,nn=23,pos;
clrscr();
for(cur=0;cur<nn;cur++)
{
for(pos=9;pos>=0;pos--)
if(arrMax[pos]<arrNum[cur])
break;
for(j=1;j<=pos;j++)
arrMax[j-1]=arrMax[j];
if(pos>=0)
arrMax[pos]=arrNum[cur];
}
for(i=0;i<10;i++)
printf("%d ",arrMax[i]);
getch();
}
When improving efficiency of an algorithm, it is often best (and instructive) to start with a naive implementation and improve it. Since in your question you obviously don't even have that, efficiency is perhaps a moot point.
If you start with the simpler question of how to find the largest integer:
Initialise largest_found to INT_MIN
Iterate the array with :
IF value > largest_found THEN largest_found = value
To get the 10 largest, you perform the same algorithm 10 times, but retaining the last_largest and its index from the previous iteration, modify the largest_found test thus:
IF value > largest_found &&
value <= last_largest_found &&
index != last_largest_index
THEN
largest_found = last_largest_found = value
last_largest_index = index
Start with that, then ask yourself (or here) about efficiency.

Why is this code for implementing mergesort not producing correct result?

Here in I'm trying to implement mergesort on array of 10 elements. On providing the input a[10]={9,8,7,6,5,4,3,2,1,0} , I obtain the output as {0,0,1,1,0, 4,4,4,3,2} while the expected output is {0,1,2,3,4,5,6,7,8,9}. I am calling the mergesort in main with l=0,h=9.
void mergesort(int a[],int l,int h)
{
int c[10];
int m=(l+h)/2;
if(l<h)
{
mergesort(a,l,m); // Recursive call to sort first half
mergesort(a,m+1,h); // Recursive call to sort second half
}
int i,k=l,j=l;
while(k<=h) // Merging the first and second half of the array
{
if(a[j]<a[m+1])
{
c[k]=a[j];
k++;
j++;
}
else
{
c[k]=a[m+1];
k++;
m++;
}
}
for(i=l;i<=h;i++)
a[i]=c[i];
}
One of the few problems: Your value of l is no longer a valid left limit after the while loop since you are incrementing it. So when you are copying from array c to a later in the for loop, you are copying invalid data.
The problem is that in your while loop you are sometimes looking outside the bounds you should be.
Assuming you put in a check at the beginning of your function saying if l==h then return (since sorting a one element array is unnecessary) then the first time it will do anything is when it recurses to mergesort(a, 0,1). Here we are basically merging two single element arrays.
When going through your loop the first time we have i,j,k,m=0. We will go into the else part of the if because element 0 is greater than 1. We thus write out a[1] into the output array and we now have i,j=0 and k,m=1. What we now should do is note that our second array is exhausted and fill from the remaining elements in the first array.
Instead what we do is compare elements j and m+1 (ie 0 and 2). This is clearly wrong because element 2 shouldn't appear in the array. We of course find element 2 is smaller and thus put that into the output array at position two. Once we copy this over a we get {8, 7, 7, 6, 5, 4, 3, 2, 1, 0} and this is where it all goes wrong.

Find n-th smallest element in array without sorting?

I want to write a program to find the n-th smallest element without using any sorting technique..
Can we do it recursively, divide and conquer style like quick-sort?
If not, how?
You can find information about that problem here: Selection algorithm.
What you are referring to is the Selection Algorithm, as previously noted. Specifically, your reference to quicksort suggests you are thinking of the partition based selection.
Here's how it works:
Like in Quicksort, you start by picking a good
pivot: something that you think is nearly
half-way through your list. Then you
go through your entire list of items
swapping things back and forth until
all the items less than your pivot
are in the beginning of the list, and
all things greater than your pivot
are at the end. Your pivot goes into the leftover spot in the middle.
Normally in a quicksort you'd recurse
on both sides of the pivot, but for
the Selection Algorithm you'll only
recurse on the side that contains the
index you are interested in. So, if
you want to find the 3rd lowest
value, recurse on whichever side
contains index 2 (because index 0 is
the 1st lowest value).
You can stop recursing when you've
narrowed the region to just the one
index. At the end, you'll have one
unsorted list of the "m-1" smallest
objects, and another unsorted list of the "n-m" largest
objects. The "m"th object will be inbetween.
This algorithm is also good for finding a sorted list of the highest m elements... just select the m'th largest element, and sort the list above it. Or, for an algorithm that is a little bit faster, do the Quicksort algorithm, but decline to recurse into regions not overlapping the region for which you want to find the sorted values.
The really neat thing about this is that it normally runs in O(n) time. The first time through, it sees the entire list. On the first recursion, it sees about half, then one quarter, etc. So, it looks at about 2n elements, therefore it runs in O(n) time. Unfortunately, as in quicksort, if you consistently pick a bad pivot, you'll be running in O(n2) time.
This task is quite possible to complete within roughly O(n) time (n being the length of the list) by using a heap structure (specifically, a priority queue based on a Fibonacci heap), which gives O(1) insertion time and O(log n) removal time).
Consider the task of retrieving the m-th smallest element from the list. By simply looping over the list and adding each item to the priority queue (of size m), you can effectively create a queue of each of the items in the list in O(n) time (or possibly fewer using some optimisations, though I'm not sure this is exceedingly helpful). Then, it is a straightforward matter of removing the element with lowest priority in the queue (highest priority being the smallest item), which only takes O(log m) time in total, and you're finished.
So overall, the time complexity of the algorithm would be O(n + log n), but since log n << n (i.e. n grows a lot faster than log n), this reduces to simply O(n). I don't think you'll be able to get anything significantly more efficient than this in the general case.
You can use Binary heap, if u dont want to use fibonacci heap.
Algo:
Contruct the min binary heap from the array this operation will take O(n) time.
Since this is a min binary heap, the element at the root is the minimum value.
So keep on removing element frm root, till u get ur kth minimum value. o(1) operation
Make sure after every remove you re-store the heap kO(logn) operation.
So running time here is O(klogn) + O(n)............so it is O(klogn)...
Two stacks can be used like this to locate the Nth smallest number in one pass.
Start with empty Stack-A and Stack-B
PUSH the first number into Stack-A
The next number onwards, choose to PUSH into Stack-A only if the number is smaller than its top
When you have to PUSH into Stack-A, run through these steps
While TOP of Stack-A is larger than new number, POP TOP of Stack-A and push it into Stack-B
When Stack-A goes empty or its TOP is smaller than new number, PUSH in the new number and restore the contents of Stack-B over it
At this point you have inserted the new number to its correct (sorted) place in Stack-A and Stack-B is empty again
If Stack-A depth is now sufficient you have reached the end of your search
I generally agree to Noldorins' optimization analysis.
This stack solution is towards a simple scheme that will work (with relatively more data movement -- across the two stacks). The heap scheme reduces the fetch for Nth smallest number to a tree traversal (log m).
If your target is an optimal solution (say for a large set of numbers or maybe for a programming assignment, where optimization and the demonstration of it are critical) you should use the heap technique.
The stack solution can be compressed in space requirements by implementing the two stacks within the same space of K elements (where K is the size of your data set). So, the downside is just extra stack movement as you insert.
Here is the Ans to find Kth smallest element from an array:
#include<stdio.h>
#include<conio.h>
#include<iostream>
using namespace std;
int Nthmin=0,j=0,i;
int GetNthSmall(int numbers[],int NoOfElements,int Nthsmall);
int main()
{
int size;
cout<<"Enter Size of array\n";
cin>>size;
int *arr=(int*)malloc(sizeof(int)*size);
cout<<"\nEnter array elements\n";
for(i=0;i<size;i++)
cin>>*(arr+i);
cout<<"\n";
for(i=0;i<size;i++)
cout<<*(arr+i)<<" ";
cout<<"\n";
int n=sizeof(arr)/sizeof(int);
int result=GetNthSmall(arr,size,3);
printf("Result = %d",result);
getch();
return 0;
}
int GetNthSmall(int numbers[],int NoOfElements,int Nthsmall)
{
int min=numbers[0];
while(j<Nthsmall)
{
Nthmin=numbers[0];
for(i=1;i<NoOfElements;i++)
{
if(j==0)
{
if(numbers[i]<min)
{
min=numbers[i];
}
Nthmin=min;
}
else
{
if(numbers[i]<Nthmin && numbers[i]>min)
Nthmin=numbers[i];
}
}
min=Nthmin;
j++;
}
return Nthmin;
}
The simplest way to find the nth largest element in an array without using any sorting methods.
public static void kthLargestElement() {
int[] a = { 5, 4, 3, 2, 1, 9, 8 };
int n = 3;
int max = a[0], min = a[0];
for (int i = 0; i < a.length; i++) {
if (a[i] < min) {
min = a[i];
}
if (a[i] > max) {
max = a[i];
}
}
int max1 = max, c = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[j] > min && a[j] < max) {
max = a[j];
}
}
min = max;
max = max1;
c++;
if (c == (a.length - n)) {
System.out.println(min);
}
}
}

Resources