Skip to content

Commit 4f9d782

Browse files
committed
add merge sort
1 parent 6ad75fe commit 4f9d782

File tree

7 files changed

+134
-2
lines changed

7 files changed

+134
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ The intent of this repository is to solve in **Go** the problems identified in t
5656
- [] Search an element in a sorted and rotated array
5757
- [x] [Bubble Sort](https://github.com/danrusei/algorithms_with_Go/tree/main/sorting/bubble_sort)
5858
- [x] [Insertion Sort](https://github.com/danrusei/algorithms_with_Go/tree/main/sorting/insertion_sort)
59-
- [] Merge Sort
59+
- [x] [Merge Sort](https://github.com/danrusei/algorithms_with_Go/tree/main/sorting/merge_sort)
6060
- [] Heap Sort (Binary Heap)
6161
- [x] [Quick Sort](https://github.com/danrusei/algorithms_with_Go/tree/main/sorting/quick_sort)
6262
- [] Interpolation Search

sorting/merge_sort/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Merge Sort
2+
3+
Source: [Wikipedia](https://en.wikipedia.org/wiki/Merge_sort)
4+
5+
Like QuickSort, Merge Sort is a Divide and Conquer algorithm. It divides the input array into two halves, calls itself for the two halves, and then merges the two sorted halves.
6+
7+
## Complexity
8+
9+
Worst Case Time Complexity [ Big-O ]: **O(n log n)**
10+
Best Case Time Complexity [Big-omega]: **O(n log n)**
11+
Average Time Complexity [Big-theta]: **O(n log n)**
12+
Space Complexity: **O(n)**
13+
14+
## Algorithm
15+
16+
* Divide the unsorted list into n sublists, each containing one element (a list of one element is considered sorted).
17+
* Repeatedly merge sublists to produce new sorted sublists until there is only one sublist remaining. This will be the sorted list.
18+
19+
![merge sort algorithm](merge_sort_algorithm.png)

sorting/merge_sort/merge.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package mergesort
2+
3+
func mergesort(target []int) {
4+
left := 0
5+
right := len(target) - 1
6+
sortIt(target, left, right)
7+
}
8+
9+
// run recursively with a modified left and right index of the slice
10+
func sortIt(target []int, left int, right int) {
11+
if left >= right {
12+
return
13+
}
14+
mid := (left + right - 1) / 2
15+
16+
sortIt(target, left, mid)
17+
sortIt(target, mid+1, right)
18+
19+
merge(target, left, mid, right)
20+
}
21+
22+
func merge(target []int, left int, mid int, right int) {
23+
24+
//find the sizes of the two slices
25+
n1 := mid - left + 1
26+
n2 := right - mid
27+
28+
//create temp slices
29+
leftSlice := make([]int, n1)
30+
rightSlice := make([]int, n2)
31+
32+
//copy data to the temp slices
33+
for i := 0; i < n1; i++ {
34+
leftSlice[i] = target[left+i]
35+
}
36+
for j := 0; j < n2; j++ {
37+
rightSlice[j] = target[mid+1+j]
38+
}
39+
40+
//merge the temp slices
41+
var i, j = 0, 0
42+
k := left
43+
44+
for i < n1 && j < n2 {
45+
if leftSlice[i] <= rightSlice[j] {
46+
target[k] = leftSlice[i]
47+
i++
48+
} else {
49+
target[k] = rightSlice[j]
50+
j++
51+
}
52+
k++
53+
}
54+
55+
//copy the remaining elements from leftSlice
56+
for i < n1 {
57+
target[k] = leftSlice[i]
58+
i++
59+
k++
60+
}
61+
62+
//copy the remaining elements from leftSlice
63+
for j < n2 {
64+
target[k] = rightSlice[j]
65+
j++
66+
k++
67+
}
68+
}
61.6 KB
Loading

sorting/merge_sort/merge_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package mergesort
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestMergeSort(t *testing.T) {
9+
for _, tc := range testcases {
10+
t.Run(tc.name, func(t *testing.T) {
11+
mergesort(tc.original)
12+
if !reflect.DeepEqual(tc.original, tc.sorted) {
13+
t.Errorf("got: %v, want: %v", tc.original, tc.sorted)
14+
}
15+
})
16+
}
17+
}

sorting/merge_sort/test_cases.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package mergesort
2+
3+
var testcases = []struct {
4+
name string
5+
original []int
6+
sorted []int
7+
}{
8+
{
9+
name: "4 elements in list",
10+
original: []int{4, 2, 3, 1},
11+
sorted: []int{1, 2, 3, 4},
12+
},
13+
{
14+
name: "empty list",
15+
original: []int{},
16+
sorted: []int{},
17+
},
18+
{
19+
name: "already sorted list",
20+
original: []int{10, 20, 30, 40},
21+
sorted: []int{10, 20, 30, 40},
22+
},
23+
{
24+
name: "9 elements in the list",
25+
original: []int{11, 21, 12, 4, 3, 100, 1000, 1, 123},
26+
sorted: []int{1, 3, 4, 11, 12, 21, 100, 123, 1000},
27+
},
28+
}

sorting/quick_sort/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Quicksort is a divide-and-conquer algorithm. It works by selecting a 'pivot' ele
77
## Complexity
88

99
Worst Case Time Complexity [ Big-O ]: **O(n2)**
10-
Best Case Time Complexity [Big-omega]: **O(n log n)**
10+
Best Case Time Complexity [Big-omega]: **O(n log n)**
1111
Average Time Complexity [Big-theta]: **O(n log n)**
1212
Space Complexity: **O(n)**
1313

0 commit comments

Comments
 (0)