Пример #1
0
/*!the insertion sort
 *
 * <pre>
 * old:     5       2       6       2       8       6       1
 *
 *        (hole)
 * step1: ((5))     2       6       2       8       6       1
 *        (next) <=
 *
 *        (hole)  
 * step2: ((2))    (5)      6       2       8       6       1
 *                (next) <=
 *
 *                        (hole)
 * step3:   2       5     ((6))     2       8       6       1
 *                        (next) <=
 *
 *                 (hole)       
 * step4:   2      ((2))   (5)     (6)      8       6       1
 *                                (next) <=
 *
 *                                        (hole)
 * step5:   2       2       5       6     ((8))     6       1
 *                                        (next) <=
 *
 *                                        (hole) 
 * step6:   2       2       5       6     ((6))    (8)       1
 *                                                (next) <=
 *
 *        (hole)                                         
 * step7: ((1))    (2)     (2)     (5)     (6)     (6)      (8)       
 *                                                        (next)
 * </pre>
 */
tb_void_t tb_insert_sort(tb_iterator_ref_t iterator, tb_size_t head, tb_size_t tail, tb_iterator_comp_t comp)
{   
    // check
    tb_assert_and_check_return(iterator);
    tb_assert_and_check_return((tb_iterator_mode(iterator) & TB_ITERATOR_MODE_FORWARD));
    tb_assert_and_check_return((tb_iterator_mode(iterator) & TB_ITERATOR_MODE_REVERSE));
    tb_check_return(head != tail);
    
    // init
    tb_size_t       step = tb_iterator_step(iterator);
    tb_pointer_t    temp = step > sizeof(tb_pointer_t)? tb_malloc(step) : tb_null;
    tb_assert_and_check_return(step <= sizeof(tb_pointer_t) || temp);

    // the comparer
    if (!comp) comp = tb_iterator_comp;

    // sort
    tb_size_t last, next;
    for (next = tb_iterator_next(iterator, head); next != tail; next = tb_iterator_next(iterator, next))
    {
        // save next
        if (step <= sizeof(tb_pointer_t)) temp = tb_iterator_item(iterator, next);
        else tb_memcpy(temp, tb_iterator_item(iterator, next), step);

        // look for hole and move elements[hole, next - 1] => [hole + 1, next]
        for (last = next; last != head && (last = tb_iterator_prev(iterator, last), comp(iterator, temp, tb_iterator_item(iterator, last)) < 0); next = last)
                tb_iterator_copy(iterator, next, tb_iterator_item(iterator, last));

        // item => hole
        tb_iterator_copy(iterator, next, temp);
    }

    // free
    if (temp && step > sizeof(tb_pointer_t)) tb_free(temp);
}
Пример #2
0
static __tb_inline__ tb_void_t tb_heap_push(tb_iterator_ref_t iterator, tb_size_t head, tb_size_t hole, tb_size_t top, tb_cpointer_t item, tb_iterator_comp_t comp)
{
    // check
    tb_assert_and_check_return(comp);

    // (hole - 1) / 2: the parent node of the hole
    // finds the final hole
    tb_size_t       parent = 0;
    tb_cpointer_t   parent_item = tb_null;
    for (parent = (hole - 1) >> 1; hole > top && (comp(iterator, (parent_item = tb_iterator_item(iterator, head + parent)), item) < 0); parent = (hole - 1) >> 1)
    {   
        // move item: parent => hole
//      tb_iterator_copy(iterator, head + parent, item);
        tb_iterator_copy(iterator, head + hole, parent_item);

        // move node: hole => parent
        hole = parent;
    }

    // copy item
    tb_iterator_copy(iterator, head + hole, item);
}
Пример #3
0
/*! adjust heap
 *
 * <pre>
 * init:
 *                                          16(head)
 *                               -------------------------
 *                              |                         |
 *                           (hole)                       10
 *                        --------------             -------------
 *                       |              |           |             |
 *                       8(larger)      7           9             3
 *                   ---------       ----
 *                  |         |     |
 *                  2         4     1(tail - 1)
 *
 * after:
 *                                          16(head)
 *                               -------------------------
 *                              |                         |
 *                              8                        10
 *                        --------------             -------------
 *                       |              |           |             |
 *                      (hole)          7           9             3
 *                   ---------       ----
 *                  |         |     |
 *                  2 (larger)4     1(tail - 1)
 *
 * after:
 *                                          16(head)
 *                               -------------------------
 *                              |                         |
 *                              8                        10
 *                        --------------             -------------
 *                       |              |           |             |
 *                       4              7           9             3
 *                   ---------       ----
 *                  |         |     |
 *                  2      (hole)   1(tail - 1)
 *
 * </pre>
 */
static __tb_inline__ tb_void_t tb_heap_adjust(tb_iterator_ref_t iterator, tb_size_t head, tb_size_t hole, tb_size_t tail, tb_cpointer_t item, tb_iterator_comp_t comp)
{
    // the comparer 
    if (!comp) comp = tb_iterator_comp;

#if 0
    // save top position
    tb_size_t top = hole;

    // 2 * hole + 2: the right child node of hole
    tb_size_t child = (hole << 1) + 2;
    for (; child < tail; child = (child << 1) + 2)
    {   
        // the larger child node
        if (comp(iterator, tb_iterator_item(iterator, head + child), tb_iterator_item(iterator, head + child - 1)) < 0) child--;

        // the larger child node => hole
        tb_iterator_copy(iterator, head + hole, tb_iterator_item(iterator, head + child));

        // move the hole down to it's larger child node 
        hole = child;
    }

    // no right child node? 
    if (child == tail)
    {   
        // the last child => hole
        tb_iterator_copy(iterator, head + hole, tb_iterator_item(iterator, head + tail - 1));

        // move hole down to tail
        hole = tail - 1;
    }

    // push item into the hole
    tb_heap_push(iterator, head, hole, top, item, comp);
#else

    // walk, 2 * hole + 1: the left child node of hole
    tb_size_t       child = (hole << 1) + 1;
    tb_cpointer_t   child_item = tb_null;
    tb_cpointer_t   child_item_r = tb_null;
    for (; child < tail; child = (child << 1) + 1)
    {   
        // the larger child node
        child_item = tb_iterator_item(iterator, head + child);
        if (child + 1 < tail && comp(iterator, child_item, (child_item_r = tb_iterator_item(iterator, head + child + 1))) < 0) 
        {
            child++;
            child_item = child_item_r;
        }

        // end?
        if (comp(iterator, child_item, item) < 0) break;

        // the larger child node => hole
        tb_iterator_copy(iterator, head + hole, child_item);

        // move the hole down to it's larger child node 
        hole = child;
    }

    // copy item
    tb_iterator_copy(iterator, head + hole, item);

#endif
}