Created
July 25, 2009 22:11
-
-
Save dvdsgl/155103 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void mergesort_(id* objs, size_t count, SEL cmp) | |
{ | |
// Base case. | |
if (count < 2) return; | |
size_t left_count = count / 2; | |
size_t right_count = count – left_count; | |
id left_objs[left_count]; | |
id right_objs[right_count]; | |
// Function pointer for comparison IMP. | |
compare_IMP_ cmp_IMP = (compare_IMP_)[*objs methodForSelector:cmp]; | |
// Divide and conquer. | |
memcpy(left_objs, objs, sizeof(id) * left_count); | |
memcpy(right_objs, &objs[left_count], sizeof(id) * right_count); | |
mergesort_(left_objs, left_count, cmp); | |
mergesort_(right_objs, right_count, cmp); | |
size_t cur_left = 0; | |
size_t cur_right = 0; | |
while (cur_left < left_count || cur_right < right_count) | |
{ | |
id left = left_objs[cur_left]; | |
id right = right_objs[cur_right]; | |
// Special case where right side has element(s) remaining after | |
// all left-side elements have been merged. | |
if (cur_left == left_count) { | |
objs[cur_left+cur_right] = right; | |
cur_right++; | |
} | |
// Special case where left side has element(s) remaining after | |
// all right-side elements have been merged. | |
else if (cur_right == right_count) { | |
objs[cur_left+cur_right] = left; | |
cur_left++; | |
} | |
// Normal merge case: left > right | |
else if (cmp_IMP(left, cmp, right) == NSOrderedDescending) { | |
objs[cur_left+cur_right] = right; | |
cur_right++; | |
// Normal merge case: left <= right | |
} else { | |
objs[cur_left+cur_right] = left; | |
cur_left++; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment