about the usage of modulus operator - java

this a part of code for Quick Sort algorithm but realy I do not know that why it uses rand() %n please help me thanks
Swap(V,0,rand() %n) // move pivot elem to V[0]

It is used for randomizing the Quick Sort to achieve an average of nlgn time complexity.
To Quote from Wikipedia:
What makes random pivots a good choice?
Suppose we sort the list and then
divide it into four parts. The two
parts in the middle will contain the
best pivots; each of them is larger
than at least 25% of the elements and
smaller than at least 25% of the
elements. If we could consistently
choose an element from these two
middle parts, we would only have to
split the list at most 2log2n times
before reaching lists of size 1,
yielding an algorithm.

Quick sort has its average time complexity O(nlog(n)) but worst case complexity is n^2 (when array is already sorted). So to make it O(nlog(n)) pivot is chosen randomly so rand()%n is generating a random index between 0 to n-1.

Related

Search the different number in array, when all the other numbers are same , can this be done in O(logn) using divide and conquer

Lets say we have a very large array and we need to find the only different number in the array, all the other numbers are the same in the array, can we find it in O(log n) using divide and conquer, just like mergeSort, please provide an implementation.
This cannot be done in better time complexity than O(n) unless that array is special. With the constraints you have given, even if you apply an algorithm like divide and conquer you have to visit every array element at least once.
As dividing the array will be O(log n) and comparing 2 elements when array is reduced to size 2 will be O(1)
This is wrongly put. Dividing the array is not O(log n). The reason why something like a binary search works in O(log n) is because the array is sorted and that way you can discard the other half of the array at every step even without looking at what elements they have, thereby halving the size of original problem.
Intuitively, you can think this as follows : Even if you keep on dividing the array into halves, the leaf nodes of the tree formed are n/2 (Considering you compare 2 elements at leaf). You will have to make n/2 comparisons, which leads to asymptotic complexity of O(n).

Trying to understand complexity of quick sort

I understand worst case happens when the pivot is the smallest or the largest element. Then one of the partition is empty and we repeat the recursion for N-1 elements
But how it is calculated to O(N^2)
I have read couple of articles still not able to understand it fully.
Similarly, best case is when the pivot is the median of the array and the left and right part are of the same size. But, then how the value O(NlogN) is calculated
I understand worst case happens when the pivot is the smallest or the largest element. Then one of the partition is empty and we repeat the recursion for N-1 elements.
So, imagine that you repeatedly pick the worst pivot; i.e. in the N-1 case one partition is empty and you recurse with N-2 elements, then N-3, and so on until you get to 1.
The sum of N-1 + N-2 + ... + 1 is (N * (N - 1)) / 2. (Students typically learn this in high-school maths these days ...)
O(N(N-1)/2) is the same as O(N^2). You can deduce this from first principles from the mathematical definition of Big-O notation.
Similarly, best case is when the pivot is the median of the array and the left and right part are of the same size. But, then how the value O(NlogN) is calculated.
That is a bit more complicated.
Think of the problem as a tree:
At the top level, you split the problem into two equal-sized sub problems, and move N objects into their correct partitions.
At the 2nd level. you split the two sub-problems into four sub-sub-problems, and in 2 problems you move N/2 objects into their correct partitions, for a total of N objects moved.
At the bottom level you have N/2 sub-problems of size 2 which you (notionally) split into N problems of size 1, again copying N objects.
Clearly, at each level you move N objects. The height of the tree for a problem of size N is log2N. So ... there are N * log2N object moves; i.e. O(N * log2)
But log2N is logeN * loge2. (High-school maths, again.)
So O(Nlog2N) is O(NlogN)
Little correction to your statement:
I understand worst case happens when the pivot is the smallest or the largest element.
Actually, the worst case happens when each successive pivots are the smallest or the largest element of remaining partitioned array.
To better understand the worst case: Think about an already sorted array, which you may be trying to sort.
You select first element as first pivot. After comparing the rest of the array, you would find that the n-1 elements still are on the other end (rightside) and the first element remains at the same position, which actually totally beats the purpose of partitioning. These steps you would keep repeating till the last element with the same effect, which in turn would account for (n-1 + n-2 + n-3 + ... + 1) comparisons, and that sums up to (n*(n-1))/2 comparisons. So,
O(n*(n-1)/2) = O(n^2) for worst case.
To overcome this problem, it is always recommended to pick up each successive pivots randomly.
I would try to add explanation for average case as well.
The best case can derived from the Master theorem. See https://en.wikipedia.org/wiki/Master_theorem for instance, or Cormen, Leiserson, Rivest, and Stein: Introduction to Algorithms for a proof of the theorem.
One way to think of it is the following.
If quicksort makes a poor choice for a pivot, then the pivot induces an unbalanced partition, with most of the elements being on one side of the pivot (either below or above). In an extreme case, you could have, as you suggest, that all elements are below or above the pivot. In that case we can model the time complexity of quicksort with the recurrence T(n)=T(1)+T(n-1)+O(n). However, T(1)=O(1), and we can write out the recurrence T(n)=O(n)+O(n-1)+...+O(1) = O(n^2). (One has to take care to understand what it means to sum Big-Oh terms.)
On the other hand, if quicksort repeatedly makes good pivot choices, then those pivots induce balanced partitions. In the best case, about half the elements will be below the pivot, and about half the elements above the pivot. This means we recurse on two subarrays of roughly equal sizes. The recurrence then becomes T(n)=T(n/2)+T(n/2)+O(n) = 2T(n/2)+O(n). (Here, too, one must take care about rounding the n/2 if one wants to be formal.) This solves to T(n)=O(n log n).
The intuition for the last paragraph is that we compute the relative position of the pivot in the sorted order without actually sorting the whole array. We can then compute the relative position of the pivot in the below subarray without having to worry about the elements from the above subarray; similarly for the above subarray.
Firstly, paste a pseudo-code here:
In my opinion, you need understand the two cases: the worst case & the best case.
The worst case:
The most unbalanced partition occurs when the pivot divides the list into two sublists of sizes 0 and n−1. The complexity in recursively is T(n)=O(n)+T(0)+T(n-1)=O(n)+T(n-1). The master theorem tells that
T(n)=O(n²).
The best case:
In the most balanced case, each time we perform a partition we divide the list into two nearly equal pieces. The same as the worst, the recurrence relation is T(n)=O(n)+2T(n/2). And it can transform to T(n)=O(n logn).

Finding median in unsorted array

I need to take input such as 4 1 6 5 0. The 4 determines how big the array is, and the rest are array elements. The catch is I can't sort it first. I'm at a loss of how to begin.
There Is A Chapter In MIT's Introduction To Algorithm Course (http://www.catonmat.net/blog/mit-introduction-to-algorithms-part-four) Dedicated To Order Statics. You Can Find The Median In O(N) Expected Time, O(N^2) Worst Case.
I think that you should use sorted list, it uses a perform any algorithm to sort the list. So you can sort them first and then get the n/2 element, it's your median.

What is the most inefficient sorting routine?

For an array of integers, what is the least efficient way of sorting the array. The function should make progress in each step (eg no infinity loop). What is the runtime of that algorithm?
There can be no least efficient algorithm for anything. This can easily be proved by contradiction so long as you accept that, starting from any algorithm, another equivalent but less efficient algorithm can be constructed.
Bogosort has average runtime of O(n*n!), ouch.
The stupid sort is surely the worst algorithm. It's not exactly an infinite loop but this approach has as worst case O(inf) and the avarage is O(n × n!).
You can do it in O(n!*n) by generating all unqiue permutations and afterwards checking if the array is sorted.
The least efficiant algorithm I can think with a finite upper bound on runtime is permutation sort. The idea is to generate every permutation (combination) of the inputs and check if it's sorted.
The upper bound is O(n!), the lower bound is O(n) when the array is already sorted.
Iterate over all finite sequences of integers using diagonalization.
For each sequence, test whether it's sorted.
If so, test whether its elements match the elements in your array.
This will have an upper bound (first guess: O(n^(n*m)?).
Strange question, normally we go for the fastest.
Find the highest and move it to a list. Repeat the previous step till the original list has only one element left. You are guaranteed O(N^2).
Bogosort is a worst sorting algorithm uses shuffle. But in another point of view it has low probability to sort array in one step :)
"Worstsort" has a complexity of where factorial of n iterated m times. The paper by Miguel A. Lerma can be found here.
Bogobogo sort.It's like bogo sort,shuffles.But it creates auxiliary arrays,the first one is the same array others are smaller by 1 element compared to previous one.They can be removed as well.
It's average complexity is O(N superfactorial*n). It's best case is O(N^2). Just like bogo sort it has worst case of O(inf).

split a linked list into 2 even lists containing the smallest and largest numbers

Given a linked list of integers in random order, split it into two new linked lists such that the difference in the sum of elements of each list is maximal and the length of the lists differs by no more than 1 (in the case that the original list has an odd number of elements). I can't assume that the numbers in the list are unique.
The algorithm I thought of was to do a merge sort on the original linked list (O(n·log n) time, O(n) space ) and then use a recursive function to walk to the end of the list to determine its length, doing the splitting while the recursive function is unwinding. The recursive function is O(n) time and O(n) space.
Is this the optimal solution? I can post my code if someone thinks it's relevant.
No it's not optimal; you can find the median of a list in O(n), then put half of them in one list (smaller than median or equal, upto list size be n/2) and half of them in another list ((n+1)/2). Their sum difference is maximized, and there is no need to sort (O(n·log(n)). All things will be done in O(n) (space and time).
Why do you need recursive function? While sorting list, you can count it elements. Then just split it in half. This drops O(n) space requirement.
Even if you can't count list length while sorting, it still can be split in O(n) time and O(1) space: get two list iterators on the beginning, advance first 2 elements at each step, second 1 element each step. When first reaches list end - cut at second.

Categories

Resources