Exemplo n.º 1
0
Arquivo: sort.c Projeto: ljx0305/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_void_t tb_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);

    // no elements?
    tb_check_return(head != tail);

    // readonly?
    tb_assert_and_check_return(!(tb_iterator_mode(iterator) & TB_ITERATOR_MODE_READONLY));

#ifdef TB_CONFIG_MICRO_ENABLE
    // random access iterator?
    tb_assert_and_check_return(tb_iterator_mode(iterator) & TB_ITERATOR_MODE_RACCESS);

    // sort it
    tb_quick_sort(iterator, head, tail, comp);
#else
    // random access iterator? 
    if (tb_iterator_mode(iterator) & TB_ITERATOR_MODE_RACCESS) 
    {
        if (tb_distance(iterator, head, tail) > 100000) tb_heap_sort(iterator, head, tail, comp);
        else tb_quick_sort(iterator, head, tail, comp); //!< @note the recursive stack size is limit
    }
    else tb_insert_sort(iterator, head, tail, comp);
#endif
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_void_t tb_remove_first_if(tb_iterator_ref_t iterator, tb_predicate_ref_t pred, tb_cpointer_t value)
{
    // check
    tb_assert_and_check_return(iterator && pred);

    // the iterator mode
    tb_size_t mode = tb_iterator_mode(iterator);
    tb_assert_and_check_return((mode & TB_ITERATOR_MODE_FORWARD));
    tb_assert_and_check_return(!(mode & TB_ITERATOR_MODE_READONLY));

    // done
    tb_size_t itor = tb_iterator_head(iterator);
    while (itor != tb_iterator_tail(iterator))
    {
        // done predicate
        if (pred(iterator, tb_iterator_item(iterator, itor), value))
        {
            // remove it
            tb_iterator_remove(iterator, itor);
            break;
        }
    
        // next
        itor = tb_iterator_next(iterator, itor);
    }
}
Exemplo n.º 4
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_size_t tb_rwalk(tb_iterator_ref_t iterator, tb_size_t head, tb_size_t tail, tb_rwalk_func_t func, tb_cpointer_t priv)
{
    // check
    tb_assert_and_check_return_val(iterator && (tb_iterator_mode(iterator) & TB_ITERATOR_MODE_REVERSE) && func, 0);

    // null?
    tb_check_return_val(head != tail, 0);

    // rwalk
    tb_size_t count = 0;
    tb_rfor (tb_pointer_t, item, head, tail, iterator)
    {
        // done
        if (!func(iterator, item, priv)) break;

        // count++
        count++;
    }

    // ok?
    return count;
}
Exemplo n.º 5
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_size_t tb_rfind_if(tb_iterator_ref_t iterator, tb_size_t head, tb_size_t tail, tb_predicate_ref_t pred, tb_cpointer_t value)
{
    // check
    tb_assert_and_check_return_val(pred && iterator && (tb_iterator_mode(iterator) & TB_ITERATOR_MODE_REVERSE), tb_iterator_tail(iterator));

    // null?
    tb_check_return_val(head != tail, tb_iterator_tail(iterator));

    // find
    tb_size_t itor = tail;
    tb_bool_t find = tb_false;
    do
    {
        // the previous item
        itor = tb_iterator_prev(iterator, itor);

        // comp
        if ((find = pred(iterator, tb_iterator_item(iterator, itor), value))) break;

    } while (itor != head);

    // ok?
    return find? itor : tb_iterator_tail(iterator);
}
Exemplo n.º 6
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_void_t tb_remove_if(tb_iterator_ref_t iterator, tb_iterator_comp_t comp, tb_cpointer_t priv)
{
    // check
    tb_assert_and_check_return(iterator && comp);

    // the iterator mode
    tb_size_t   mode = tb_iterator_mode(iterator);
    tb_assert_and_check_return((mode & TB_ITERATOR_MODE_FORWARD));
    tb_assert_and_check_return(!(mode & TB_ITERATOR_MODE_READONLY));

    // done
    tb_long_t   ok = 1;
    tb_size_t   size = 0;
    tb_bool_t   stop = tb_false;
    tb_bool_t   need = tb_false;
    tb_size_t   prev = tb_iterator_tail(iterator);
    tb_size_t   itor = tb_iterator_head(iterator);
    tb_size_t   base = tb_iterator_tail(iterator);
    tb_bool_t   bmutable = (mode & TB_ITERATOR_MODE_MUTABLE)? tb_true : tb_false;
    while (itor != tb_iterator_tail(iterator))
    {
        // save next
        tb_size_t next = tb_iterator_next(iterator, itor);
   
        // done func
        if ((ok = comp(iterator, tb_iterator_item(iterator, itor), priv)) < 0) stop = tb_true;

        // remove it? 
        if (!ok)
        {
            // is the first removed item?
            if (!need)
            {
                // save the removed range base
                base = prev;

                // need remove items
                need = tb_true;
            }

            // update size
            size++;
        }
       
        // the removed range have been passed or stop or end?
        if (ok || next == tb_iterator_tail(iterator))
        {
            // need remove items?
            if (need) 
            {
                // check
                tb_assert_abort(size);

                // the previous tail
                tb_size_t prev_tail = tb_iterator_tail(iterator);

                // remove items
                tb_iterator_remove_range(iterator, base, !ok? next : itor, size);

                // reset state
                need = tb_false;
                size = 0;

                // is the mutable iterator?
                if (bmutable)
                {
                    // update itor
                    prev = base;

                    // the body items are removed?
                    if (base != prev_tail)
                    {
                        // the next itor
                        itor = tb_iterator_next(iterator, base);

                        // the last item be not removed? skip the last walked item
                        if (ok)
                        {
                            prev = itor;
                            itor = tb_iterator_next(iterator, itor);
                        }
                    }
                    // the head items are removed?
                    else itor = tb_iterator_head(iterator);

                    // stop?
                    tb_check_break(!stop);

                    // continue?
                    continue ;
                }
            }

            // stop?
            tb_check_break(!stop);
        }
    
        // next
        prev = itor;
        itor = next;
    }
}