Say I have 3 sorted arrays A1, A2, A3. I want to merge them using merge aspect in merge sort. How would I find that runtime?
I can't even suggest a solution, I'm completely stuck...
Thanks!
Related
In merge sort algorithm, we divide the array we want to sort until it has 1 or 2 elements (as far as I know) and only then we start merging them. Is it possible to divide the array n times before it reaches the atomic level and start the merge from there?
E.g.: I have an array of 8 elements and I want merge sort to split it in 2 arrays of 4 elements and immediately start the merging process, without making any more divisions. Thanks in advance!
Suppose I have an unsorted array P and it's sorted equivalent P_Sorted. Suppose L and R refer to the left and right halves of P. Is there a way to recover L_Sorted and R_Sorted from P and P_Sorted in linear time without using extra memory?
For further clarification, during a recursive merge sort implementation L_Sorted and R_Sorted would be merged together to form P_Sorted, so I'm kinda looking to reverse the merge step.
In a merge sort, you divide the array into two halves recursively and merge them. So at the last merge, you would have already sorted the left and right halves - they are sorted independently - that is why divide and conquer name.
Therefore when doing a merge you can just look at the sizes of the arrays to be merged and if they are equal ( even input size ) or differ by 1 ( odd input size ), you are at the last merge. Then you could store those sorted arrays in some variable before merging them.
BUT if you are not allowed to mess with the function, and you need to work only with the sorted array and the original array, I think the solution is not straightforward. I found an url that poses this problem and a possible solution.
It seems feasible in linear time for very specific datasets:
If there is a way to tell the original position of each data element in the sorted list, for example if these are records with a creation date and a name field and the original array is in chronological order, selecting from the sorted array the elements that fall in the first or second half can be done in a single scan in linear time with no space overhead.
In the general case, sorting the left and right half seems the most efficient way to get L_sorted and R_sorted, with or without P_sorted. The time complexity is O(n.log(n)).
Merge a sorted array with unsorted array to give a final sorted array. Can it be better done, the not obvious way.
final_sorted_array=merge(sort(unsorted_array), sorted_array)
I am assuming merge step similar to found in merge sort
and we know any best is limited by O(n log n) in general. I am trying to understand how a ordered data (knowing the information about data) can be useful to what extent in general.
Suppose your first array is called A1 of n1 elements and your second one is called A2 of n2 elements:
extend the length of A1 and append A2 to it at the cost of O(n2 + c), where c is a constant. Apply quick sort and get it ordered at another cost of O( (n1+n2)*log(n1+n2) ). You mentioned you didn't want the obvious way, however, you wanted to get the job done the best way. This is likely the best way, because it allows you to still use regular arrays which are usually the fastest data structures to work in general (of course it depends specifically on which task you are working on).
However, a different possibility, is to make A1 a linked list insetad of a regular array, for the purpose of this analysis we will not consider the costs of transforming A1 from an regular array into a linked list. Therefore, the approach would be to insert ordered each element of A2 into A1. The obvious way to insert ordered would be to verify each element of A1 and then decide where to insert, at the cost of O(n1 + c) for each insertion. However, a smarter method would be to make a binary search over A1 to decide where each element of A2 should be inserted in, at the cost of O(log(n1) + c) for each insertion. In this case, there would be n2 insertions, being the total cost n2*O(log(n1) + c). In this approach you wouldn't need to move any of A1 elements, since we are assuming you use a linked list, all you need is to check these elements. That's why this asymptotic function looks better, this data structure gives you the power to only look at A1 original elements without actually moving them.
To decide which approach you should use, I recommend that you analyse the algorithm which comes after the arrays merge, choosing the option that best fits your needs.
merge two sorted arrays in-place in ascending order.
Eg:
A[]=7,15,21
B[]=5,12
Output
A[]=5,7,12
B[]=15,21
You can't take any extra memory space except few variables.
You might want to check In-place merge of two arrays) and http://www.dcs.kcl.ac.uk/technical-reports/papers/TR-04-05.pdf. How to merge two sorted arrays into a sorted array? is a simpler version of it.
Merge Sort divide the list into the smallest unit (1 element), then compare each element with the adjacent list to sort and merge the two adjacent list. Finally all the elements are sorted and merged.
I want to implement the merge sort algorithm in such a way that it divides the list into a smallest unit of two elements and then sort and merge them. ?
How i can implement that???
MERGE-SORT (A, p, r)
IF p < r // Check for base case
THEN q = FLOOR[(p + r)/2] // Divide step
MERGE (A, p, q) // Conquer step.
MERGE (A, q + 1, r) // Conquer step.
MERGE (A, p, q, r) // Conquer step.
something like p < r+1 .
I've done something that sounds this before. Here are 2 variations.
Variation 1: Go through the list, sorting each pair. Then go through the list, merging each pair of pairs. Then each pair of 4s, and so on. When you've merged the whole list, you're done.
Variation 2: Have a stack of sorted arrays. Each element merges into the bottom array, and then cascade, but merging down until there is only one, or the second from the top is larger than the top. After your last element has been added, collapse the array by merging it.
The case where I've used variation 2 was one where I had a very large amount of data streaming in. I kept the first few stacks of sorted arrays in memory, and then later ones stored on disk. This lead to good locality of reference, and efficient use of disk. (You ask why I didn't use an off the shelf solution? Well the dataset I had coming in was bigger than the disk I had to handle it on, there was custom merging logic in there, and the sort really wasn't that hard to write.)