/* * Given the current matching tree, merge it with the tree generated from * the given nodes and expression. */ local UCase * merge(UCase *old) { Natural i; LCase *lcase; switch (old->uc_class) { case UC_F_NOMATCH or UC_L_NOMATCH: /* do all the matching */ return gen_tree(cur_match, old); case UC_SUCCESS: if (old->uc_size < cur_size) /* maybe more specific */ return gen_tree(cur_match, old); when UC_CASE: if (cur_match < m_end && (cur_match->level < old->uc_level || (cur_match->level == old->uc_level && p_less(cur_match->where, old->uc_path)))) { old->uc_references += old->uc_cases->lc_arity - 1; return new_node(cur_match, old, sub_merge(old)); } if (old->uc_references > 1) { old->uc_references--; old = copy_ucase(old); } lcase = old->uc_cases; if (cur_match == m_end || old->uc_level < cur_match->level || (old->uc_level == cur_match->level && p_less(old->uc_path, cur_match->where))) limb_map(lcase, merge); else { /* same place -- keep following */ i = cur_match->index; if (lcase->lc_class == LC_CHARACTER) ca_assign(lcase->lc_c_limbs, i, sub_merge(ca_index( lcase->lc_c_limbs, i))); else lcase->lc_limbs[i] = sub_merge(lcase->lc_limbs[i]); } otherwise: NOT_REACHED; } return old; }
void merge_sort(int* arr, int len) { int* helpArr = malloc(sizeof(int)*len); int width = 1; int* pSrc = arr; int* pDst = helpArr; while (width < len) { for (int i = 0; i < len; i = i+2*width) { sub_merge(pSrc, i, MIN(i+width, len), MIN(i+2*width, len), pDst); } width *= 2; int *tmp = pSrc; pSrc = pDst; pDst = tmp; } if (pSrc != arr) memcpy(arr, pSrc, sizeof(int)*len); free(helpArr); }