Login Register






Introduction to Sorting and Sorting Algorithms - Part 2 filter_list
Author
Message
Introduction to Sorting and Sorting Algorithms - Part 2 #1
Merge Sort
What is Merge Sort?
It is a sorting algorithm which uses comparison operator (=<) to choose which items of the 2 should be placed first, In fact it uses a well known method of "Divide and Conquer" to perform it's task.

Since the term MergeSort has 2 parts:

1) Merge
2) Sort


So I'll be explaining each part first and then will explain as whole In this way you'll under this better.

Understanding Divide and Conquer
This is an algorithmic approach, to break down tasks into sub task and then split these sub tasks to smaller sub tasks and going further until the condition reaches that it becomes simple enough to perform the task, Divide and Conquer is said to increase the efficiency of an algorithm because it breaks down hefty task into simple ones.

In order to understand the working, consider an array containing 6 integer values,

Code:
array = [1,3,2,8,5,9]


Take a look at this pseudo code for our Divide And Conquer,

Code:
int middle = lenght.array / 2 array left, right; loop through array: for items before mid: put them in left for items after mid: put them in right call divide on left array again

First when this divide function is called, it first finds the middle point of the array using which it can DIVIDE the array into two parts i.e Left and Right

Since the length of the array is 6, 6 / 2 = 3. The index 3 is our middle point and the item at index 3 is 8.

Hence when divide executes, it will separate all the items after and before 8, So

Code:
-> [1,3,2,8,5,9] -> [1,3,2,| 8 |,5,9] | Mid Point

Then the divide code will move toward the loop, The first line in the loop is to put all the items before and including 8 in the left array, So

Code:
-> [1,3,2,8 <- ,5,9] -> left = [1,2,3,8]

It has inserted all the items in the array left, Now insert all the items after 8 into right,

Code:
-> [1,3,2,8 -> ,5,9] -> right = [5,9]

Now, we can see, the initial array has been split into 2 other smaller arrays. Divide and Conquer is a Recursive algorithm, The condition for divide and conquer is to split a problem to an extent that it becomes easy to manage it. For us converting the list into sub arrays of length 1 is the job of Divide and Conquer and this can only be achieved by calling it again and again unless it fulfills the condition (Recursion)

To convert the list into more simpler one's we need to call it again which we did at the end for the left array, So lets cal divide on left array

Code:
-> left = [1,2,3,8]

It will find the middle point again which comes to be 2,

Code:
-> [1,2,| 3 |,8] -> left = [1,2,3] -> right = [8]

Once more we call it on the left,

Code:
-> [1, | 2 |,3] -> Left = [1,2] -> Right = [3]

And again,

Code:
-> [1,2] -> Left = [1] -> Right = [2]

No need to call divide and conquer again as the list has been broken down enough that we can call on the next function to sort it out. You see at each recursive call to the divide and conquer function, The list gets split into smaller and smaller sub lists, This is what Divide and Conquer does!

When a list has one element we call it sorted (As it has no other elements to be matched or compared with), So when Divide and Conquer creates a list which has 2 items, it splits them into half and then calls a function known as merge on them which we will study next.

Understand Merging

Merging is a process where you get to join two items (In case of our algorithm), but before joining this merge process compares the two given list, Lets take an example of 2 list items,

Code:
Left = 5 Right = 2

Now when merge is called onto left and right list, this function will first compare both of them, making the following conditions:

Code:
1) If left[item] < right[item] Put left item first then right 2) If right[item] > left[item] Put right item before left item 3) Put leftover items in the end

So,
Code:
left = [5] right = [2] --> [5] < [2] (False) --> [5] > [2] (True) result = [2] [5]

Now at the end these two items get Merged into one list

Code:
[2,5]

In simple words, this function simply compares the two items, pick smaller of them, sorts them and then merges them into one.


Merge Sort Steps of Working

Merge Sort uses the following list of steps to perform it's job:

1) Divide
Divide the given list into sub list until each list contains 1 element

2) Conquer
Sort 2 sub list using merge recursion

3) Combine
When the two sub list are sorted, Merge them to produce a sorted list

Lets learn how Divide and Conquer is used by Merge Sort to do it's sorting, We will take a 7 length array

Code:
array = [5,9,1,4,10,12,8]

First we call our divide function,

Code:
-> [5,9,1,4,10,12,8] -> [5,9,1,4] [10,12,8] -> [5,9] [1,4] [10,12] [8] -> [5] [9] [1] [4] [10] [12] [8]

This was achieved by the recursive calls to our divide function

Now we will call merge function on each of the two items,

Code:
-> [5] [9] [1] [4] [10] [12] [8] -> ([5] [9]) ([1] [4]) ([10] [12]) ([8]) | | | | -> [5,9] [1,4] [10,12] [8]

Each of the two items are first compared keeping the strict conditions of the merge that we discussed,

As 5 is less than 9, hence it's in sorted form and the merge function merges them into one list exactly, same goes for the others. You might be noticing that lonely 8 at the end, If you recall, I did state that list with length 1 are considered sorted, hence 8 will continue as it is to the next step.

The next step is to call merge on these newly made lists, now the 2 list will get compared again

Code:
-> ([5,9] [1,4]) ([10,12] [8]) | | -> [1,4,5,9] [8,10,12]

The same process happened here, the right and left list items are compared, and put into order Lets visualize:

Code:
([5,9] [1,4])

Item 5 of left list is compared to 1 of the right, Since 5 > 1 hence the resulting list will be,

Code:
[1]

Then 5 is compared with 4, Since 5 > 4,

Code:
[1,4]

The leftover list is [5,9] so it gets merge at the end,

Code:
[1,4,5,9]

Now these last two remaining lists are merged further,

Code:
-> [1,4,5,9] [8,10,12] -> [1,4,5,8,9,10,12]

And we have a Sorted list using Merge Sort

Here's the whole process,

Code:
-> [5,9,1,4,10,12,8] | -> [5,9,1,4] [10,12,8] | | -> [5,9] [1,4] [10,12] [8] | | | | -> [5] [9] [1] [4] [10] [12] [8] | | | | | | -> ([5] [9]) ([1] [4]) ([10] [12]) ([8]) | | | | -> [5,9] [1,4] [10,12] [8] | | -> ([5,9] [1,4]) ([10,12] [8]) | | -> [1,4,5,9] [8,10,12] | | -> ([1,4,5,9] [8,10,12]) | -> [1,4,5,8,9,10,12]

Image:

[Image: Merge-sort-example-300px.gif]

[Image: mergesortA.png]

[Image: mergesortB.png]

So merge sort actually splits the list into simpler ones, sorts em and merges them together. In the process tree you can see that after the middle of the tree the inverse process begins i.e First the list is split, then again it's merged back into one.

Here's one of my Merge Sort Implementation In C++:

Code:
#include "stdafx.h" #include "iostream" #include "vector" std::vector<int> merge_list(std::vector<int> left, std::vector<int> right) { //This vector holds all the items in sorted form at the end std::vector<int>result; //These variables will be used to iterate through the items int go_left = 0, go_right = 0; //Compare the size of the respective vectors until none of the item is left to be sorted while (go_left < left.size() && go_right < right.size()) { //Then compare the first 2 if (left[go_left] <= right[go_right]) { //The smaller item gets inserted into the result vector result.push_back(left[go_left]); //Increase by 1 go_left++; } else { //This is the part where the smaller item from the right vector gets inserted result.push_back(right[go_right]); //Increase by 1 go_right++; } } //Insert the rest of the items till the point where none remains to be sorted while (go_left < left.size()) //For the left vector { result.push_back(left[go_left]); //Insert into result go_left++;//Increase by 1 } while (go_right < right.size())//For the right vector { result.push_back(right[go_right]); //Insert into result go_right++;//Increase by 1 } //This finally returns the resultant vector (It might be the sublist or completly sorted) :) return result; } std::vector<int> merge_sort(std::vector<int> list) { //If the size(Number of items) is 1, Consider the list sorted if (list.size() <= 1) return list; //Find the midddle item of the list int mid = (list.size() / 2); //Vector to add items before the middle part std::vector<int>left; //Vector to add items after the middle part std::vector<int>right; //Vector iterator to loop through the vector and find the middle part and copy the items before it for (std::vector<int>::const_iterator it = list.begin(), end = list.end() - mid; it != end; ++it) left.push_back(*it); //Vector iterator to loop through the vector and find the middle part and copy the items after it for (std::vector<int>::const_iterator it = list.begin() + mid, end = list.end(); it != end; ++it) right.push_back(*it); //Recursive call to further merge the lists right = merge_sort(right); left = merge_sort(left); //Call the merge list function and return the sorted list return merge_list(left, right); } int _tmain(int argc, _TCHAR* argv[]) { std::vector<int> x = { 5, 90, 10, 18, 100, 201, 1, 11 }; int middle = (x.size() / 2); std::vector<int> sorted = merge_sort(x); std::cout << "Your sorted List is: " << "\n"; for (std::vector<int>::const_iterator it = sorted.begin(), end = sorted.end(); it != end; ++it){ std::cout << " " << *it << "\n"; } }

Advantages of Merge Sort:

1) It's faster even in worst cases, its complexity is same in both cases. For n = 20, it's 4.6 times faster than bubble sort. Merge sort's time complexity is Theta(nlg n) and space is BigOh(n), Merge sort is a very good sorting algorithm for n (input size) is very large.

Disadvantages:

Slower than non-comparison based algorithms


More Advantages: http://www.site.uottawa.ca/~nat/Courses/...sld026.htm

This ends my tutorial on Merge Sort, I hope you didn't find it confusing. Reading it 2 to 3 times will get it right. If you need any help I'm always available to answer your query via PM or email. For any corrections PM me

References: http://interactivepython.org/courselib/s...mergesorta, Wikipedia

Credits: @Psycho_Coder for his suggestions
My Blog: http://www.procurity.wordpress.com
Donations: 1HLjiSbnWMpeQU46eUVCrYdbkrtduX7snG

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #2
Good job. A few things that you should have taken care of :-

1. A bit more explanation for the Divide and conquer method
2. In the advantages of merge sort you said its easy to implement but again in the disadvantages you're saying that it is difficult for beginners to implement. This is quite wrong as its actually easy to implement but the concept is not very easy. So, I would prefer to remove that second point from disadvantages and from advantages as well, because its really not some advantage. The most important thing is understanding how the recursion tree works, and drawing it manually by using pen and paper, how CPU does these using the system stack (the concepts behind recursion). That concept is quite challenging to understand.

http://www.site.uottawa.ca/~nat/Courses/...sld026.htm

For your information :-

Merge sort's time complexity is Theta(nlg n) and space is BigOh(nlg n). Merge sort is a very good sorting algorithm for n (input size) is very large. But for fewer elements like 100s, insertion sort would be better. Quick sort is another sorting algorithm which is better than Merge sort.

In Java We have Collections.sort() and Arrays.sort() which uses Merge sort but its time complexity is Theta(lg n) and the difference is because Java uses an optimized version of Merge sort which better than quick sort and has logarithmic time complexity.

You can even find something like External merge sort. Read about it here : The Art of Computer Programming, Volume 3: Sorting and Searching, Second Edition, Section 5.4: External Sorting, page : 248–379.

It has been written very well by Sir Knuth


By the way if you can then you can submit the merge sort code here :- http://www.hackcommunity.com/Thread-Reso...Algorithms

However good job as you're really contributing to the HC Dev's project. Myself being an HC Dev, I am unable to post the tutorials though I have three tutorials saved as draft. I am having a few IRL issues and I don't get much time to work for it. I will have to find time for this somehow.

Keep up the good work.


Thank you,
Sincerely,
Psycho_COder
[Image: OilyCostlyEwe.gif]

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #3
@Psycho_Coder Thanks buddy, I'll be improving the things you've highlighted
My Blog: http://www.procurity.wordpress.com
Donations: 1HLjiSbnWMpeQU46eUVCrYdbkrtduX7snG

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #4
Tell me one thing which software did you use to make that animated gif to show the working of merge sort
[Image: OilyCostlyEwe.gif]

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #5
(11-20-2013, 02:45 PM)Psycho_Coder Wrote: Tell me one thing which software did you use to make that animated gif to show the working of merge sort

Took it from Wikipedia, It has good animations for Sorting Algorithms Smile
My Blog: http://www.procurity.wordpress.com
Donations: 1HLjiSbnWMpeQU46eUVCrYdbkrtduX7snG

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #6
Hey @Ex094 I made a little mistake earlier, the worst case space complexity of merge sort is BigOh(n) and not BigOh(nlg n) I just made a typographical mistake, I just saw that. Very sorry for troubling you.
[Image: OilyCostlyEwe.gif]

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #7
(11-20-2013, 02:56 PM)Psycho_Coder Wrote: Hey @Ex094 I made a little mistake earlier, the worst case space complexity of merge sort is BigOh(n) and not BigOh(nlg n) I just made a typographical mistake, I just saw that. Very sorry for troubling you.
No Problem, Mistake Corrected Smile
My Blog: http://www.procurity.wordpress.com
Donations: 1HLjiSbnWMpeQU46eUVCrYdbkrtduX7snG

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #8
Update: Rewrote the divide and conquer explanation, I hope it's better for all of you to understand Smile
Regards,
Ex094
My Blog: http://www.procurity.wordpress.com
Donations: 1HLjiSbnWMpeQU46eUVCrYdbkrtduX7snG

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #9
Update: Rewrote the divide and conquer explanation, I hope it's better for all of you to understand Smile
Regards,
Ex094
My Blog: http://www.procurity.wordpress.com
Donations: 1HLjiSbnWMpeQU46eUVCrYdbkrtduX7snG

Reply

RE: Introduction to Sorting and Sorting Algorithms - Part 2 #10
Added the Tutorial Tag.
[Image: OilyCostlyEwe.gif]

Reply