Selection sort implementation, I am stuck at calculating time complexity for number of swaps - time-complexity

static int count = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
swap(arr, i, j);
count++;
}
}
}
Is this the correct implementation for selection sort? I am not getting O(n-1) complexity for swaps with this implementation.

Is this the correct implementation for selection sort?
It depends, logically what you are doing is correct. It sort using "find the max/min value in the array". But, in Selection Sort, usually you didn't need more than one swap in one iteration. You just save the max/min value in the array, then at the end you swap it with the i-th element
I am not getting O(n-1) complexity for swaps
did you mean n-1 times of swap? yes, it happen because you swap every times find a larger value not only on the largest value. You can try to rewrite your code like this:
static int count=0;
static int maximum=0;
for(int i=0;i<arr.length-1;i++){
maximum = i;
for(int j=i+1;j<arr.length;j++){
if(arr[j] > arr[maximum]){
maximum = j;
}
}
swap(arr[maximum],arr[i]);
count++;
}
Also, if you want to exact n-1 times swap, your iteration for i should changed too.

Related

Calculating Big O and time complexity of code as a linked list vs array based

Hi I'm trying to calculate the big O notation of this code, assuming the list that is being used is a linked list
public static void update(List<Star> list) {
// compute and apply acceleration
for (int i = 0; i < list.size(); i++) {
Star s1 = list.get(i);
for (int j = i + 1; j < list.size(); j++) {
Star s2 = list.get(j);
Vector acceleration = attractionAcceleration(s1, s2);
s1.velocity.add(acceleration);
acceleration.negate();
s2.velocity.add(acceleration);
}
}
// apply velocity
for (int i = 0; i < list.size(); i++) {
Star s = list.get(i);
s.location.add(s.velocity);
}
}
}
I was also asked to calculate the big O assuming the list is an array based list and I got O(N^2) due to it being 2 nested loops. I have been told that the answer for it as a linked list is O(N^4), i'm just not sure how I explain either of these calculations completely
When calculating the linked list, remember that list.get is O(N). So for the first two lines of your code, you have O(N^2) for lists and O(N) for arrays.
for (int i = 0; i < list.size(); i++) { O(N) for both
Star s1 = list.get(i); O(N) for list, O(1) for array
for (int j = i + 1; j < list.size(); j++) { O(N) for both
Star s2 = list.get(j); O(N) for list, O(1) for array
}
}
So you have two extra O(N) for lists. The nested for loops multiply, and Star s1... adds, since it is not in the internal loop, giving O(N^3) for the acceleration phase.

Time complexity of variable assignation

I know that if I have a function like:
public int addOne(int a){
return (a+1)
}
The time complexity order will be O(1) since we only do one operation (the sum).
But what if I have a function that doesn't do any operations, just assigns some values to some global variables. Like this:
public void assignValues(){
a = 2;
b = 3;
c = 4;
//maybe more
}
What would the time complexity be for this function? My guess is that it would still O(1). Is that correct?
When you discuss the time complexity of an algorithm, you first have to define the variable parameter(s). For example, it doesn't make any sense to say that something is O(n) without defining what you measure by n (e.g. the length of an array? The size of the contents of an array? The bit-length of a number? The absolute value of an integer?).
In your particular case, you have a function that takes no parameters. Assuming that the operations within the function don't depend on any other external parameters, the complexity of such a function is always trivially O(1), no matter what operations you perform inside. For example, the following function is also O(1):
public static int DoSth() {
int x = 0;
const int n = 1000000;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
x++;
return x;
}
As already mentioned, this assumes that the parameter-less function has no external dependencies. Consider e.g. the following function
public static void DoSth() {
int n = DateTime.Now.Ticks;
for(int i = 0; i < n; i++)
Console.WriteLine(i);
}
This function is O(n log n) if n is the amount of time that has passed since 1.1.0001.

Making an incremental for loop end by a certain number in objective-c

I'm trying to find a solution to this coding problem:
Create a for loop that will begin with a value of 5 and end with a value of 25. In each iteration, add the incrementing value to mathTotal. (HINT: the last value used INSIDE the loop should be 25)
But the way I can think of doing it returns with a final number for mathTotal of 26. I'm not sure how to manipulate the code to stop at 25 without actually doing the math to figure out what number to make the condition for the program to stop running.
This is what I have:
int mathTotal;
for(int i = 5; mathTotal <=25; i++) {
mathTotal = mathTotal + i;
}
I know this is a simple problem, but I'm learning how to code and don't want to move on without fully understanding something.
Thank you!
There are two major issues:
mathTotal is not initialized. You have to set an initial value.
int mathTotal = 0;
The upper border (the second parameter of the for loop) is defined as mathTotal <= 25 – rather than i <= 25 – which will be reached when i is 8.
for (int i = 5; i <=25; i++) {
mathTotal = mathTotal + i;
}
The traditional for loop in Objective-C is inherited from standard C and takes the following form:
for (/* Instantiate local variables*/ ; /* Condition to keep looping. */ ; /* End of loop expressions */)
{
// Do something.
}
For example, to print the numbers from 1 to 10, you could use the for loop:
for (int i = 1; i <= 10; i++)
{
NSLog(#"%d", i); //do something
}
This is logically equivilant to the following traditional for loop:
for (int i = 0; i < [yourArray count]; i++)
{
NSLog([myArrayOfStrings objectAtIndex:i]);
}
Your Doubt
int mathTotal = 0;
for (i = 5 = 0; i <=25 ; i++)
{
mathTotal = mathTotal + i;
}

My quicksort crashes on already sorted data

I wanted to check the performance time for different data in array (random, already sorted, sorted in descending order).
void Quicksort(int *T, int Lo, int Hi)
{
if (Lo<Hi){
int x=T[Lo];
int i=Lo, j=Hi;
do
{
while (T[i] < x) ++i;
while (T[j] > x) --j;
if (i<=j)
{
int tmp = T[i];
T[i] = T[j];
T[j] = tmp;
++i; --j;
}
} while(i < j);
if (Lo < j) Quicksort(T, Lo, j);
if (Hi > i) Quicksort(T, i, Hi);
}
}
Here are the functions used to generate and fill the testing array:
int* createArr(int length){
int* Arr= new int[length];
return Arr;
}
void Random(int *A, int length){
for (int i=0;i<length;i++){
A[i]=rand();
}
}
void Order(int *A, int length){
for (int i=0;i<length;i++){
A[i]=i;
}
}
void Backwards(int *A, int length){
for (int i=0;i<length;i++){
A[i]=length-i;
}
}
It works fine for random numbers, but when I try to fill it in ascending order and sort, it crashes with stack overflow. Can anyone give me a hint of why is it happening?
When you choose the [Lo] item as a partioning value (a pivot), and the array is already sorted, then you get a partitioning 1 to (length–1). This causes the next (recursive) call on a longer part of the array to handle just one item less then the previous level. So, as #AlexanderM noted, you will get as deep into the recursion as the length of your array. If the array is big, it will almost certainly cause the stack overflow.
Try using a tail reursion: check which part is shorter and sort it with a resursive call, then continue on the current level with the longer part. To do that replace the very first if with while and replace
if (Lo < j) Quicksort(T, Lo, j);
if (Hi > i) Quicksort(T, i, Hi);
with
if (j-Lo < Hi-i)
{
Quicksort(T, Lo, j);
Lo = i;
}
else
{
Quicksort(T, i, Hi);
Hi = j;
}
This won't make the program any faster – it will still need O(n^2) time on an already-sorted array, but will protect against linear stack memory usage, keeping it at worst O(log n).
For further directions concerning better performance see Wikipedia article Quicksort, part Choice of pivot.

Finding the number of factors using a while loop

so i have this method that finds the number of factors of a given number. It works fine and everything but i am using a for loop and my teacher is wanting me to change it into a while loop to make it more efficient, ive tried to change it but i keep getting endless loop here is the code i have using a for loop what might be a good to change it to a while loop without using a break and only having one return statement in the whole method
public static int numberOfFactors(int num){
int i;
int total=0;
for(i=1;i<=num;i++){
if(num%i==0)
total++;
}
return (total);}
I fail to see how:
i = 1;
while(i <= num) {
// do things
i++;
}
Is any more efficient than:
for( i=1; i<=num; i++) {
// do things
}
As far as I can tell? It's not! I'd love to know why your teacher thinks it is.
That said, here's what you can do to make it more efficient:
Calculate the square root of num and put it in sqrtnum as an integer, rounded down.
Change your loop to for(i=1; i<sqrtnum; i++) (note <, not <=)
If num%i==0, increment total by 2, instead of 1.
After the loop, check if sqrtnum*sqrtnum == num - if so, increment total by 1.
In this way, you only have to loop through a fraction of the numbers ;)
Not any more efficient but....
public static int numberOfFactors(int num) {
int total = 0;
int i = 1;
while(i <= num) {
if(num%i == 0)
total++;
i++;
}
return total;
}