TBOX提供了各种常用算法,对容器中的元素进行各种操作,这里主要介绍下排序和查找算法。

    排序算法目前支持如下几种:

    1. 快速排序:tb_quick_sort
    2. 堆排序: tb_heap_sort
    3. 插入排序:tb_bubble_sort
    4. 冒泡排序:tb_insert_sort

    并且提供通用的tb_sort接口,对各种排序算法进行自动适配,使得任何情况下,性能都是最优的。 例如:

    1. 对具有随机迭代特性的容器,采用库快速排序来优化
    2. 对具有随机迭代特性,并且是超大规模的容器,采用堆排序
    3. 对只能线性迭代的容器采用冒泡排序

    所以一般情况下,只需要调用tb_sort就行了

    1. // 初始化一个vector,元素类型为tb_long_t, 满256个元素自动增长
    2. tb_vector_ref_t vector = tb_vector_init(256, tb_element_long());
    3. if (vector)
    4. {
    5. // 插入一些元素
    6. tb_vector_insert_tail(vector, (tb_cpointer_t)10);
    7. tb_vector_insert_tail(vector, (tb_cpointer_t)2);
    8. tb_vector_insert_tail(vector, (tb_cpointer_t)5);
    9. tb_vector_insert_tail(vector, (tb_cpointer_t)6);
    10. tb_vector_insert_tail(vector, (tb_cpointer_t)9);
    11.  
    12. // 排序所有,第二个参数是比较器函数,默认使用容器内置的比较器
    13. tb_sort_all(vector, tb_null);
    14.  
    15. // 释放vector
    16. tb_vector_exit(vector);
    17. }

    对于查找算法,目前提供:

    1. 线性查找: tb_find
    2. 反向线性查找:tb_rfind
    3. 二分法查找: tb_binary_find

    如果容器具有随机迭代特性,你就可以使用二分查找来优化,例如:vector、原生数组等等。。

    1. // 初始化一个vector,元素类型为tb_long_t, 满256个元素自动增长
    2. tb_vector_ref_t vector = tb_vector_init(256, tb_element_long());
    3. if (vector)
    4. {
    5. // 插入一些有序元素
    6. tb_vector_insert_tail(vector, (tb_cpointer_t)1);
    7. tb_vector_insert_tail(vector, (tb_cpointer_t)2);
    8. tb_vector_insert_tail(vector, (tb_cpointer_t)4);
    9. tb_vector_insert_tail(vector, (tb_cpointer_t)6);
    10. tb_vector_insert_tail(vector, (tb_cpointer_t)9);
    11.  
    12. // 使用二分查找法,快速查找元素,算法复杂度O(log2)
    13. tb_size_t itor = tb_binary_find_all(vector, (tb_cpointer_t)5);
    14. if (itor != tb_iterator_tail(vector))
    15. {
    16. // 获取元素值:5
    17. tb_size_t value = tb_iterator_item(vector, itor);
    18. }
    19.  
    20. // 释放vector
    21. tb_vector_exit(vector);
    22. }

    你也可以指定谓词函数,来更灵活的进行查找。

    1. // 初始化一个vector,元素类型为tb_long_t, 满256个元素自动增长
    2. tb_vector_ref_t vector = tb_vector_init(256, tb_element_long());
    3. if (vector)
    4. {
    5. // 插入一些有序元素
    6. tb_vector_insert_tail(vector, (tb_cpointer_t)1);
    7. tb_vector_insert_tail(vector, (tb_cpointer_t)2);
    8. tb_vector_insert_tail(vector, (tb_cpointer_t)4);
    9. tb_vector_insert_tail(vector, (tb_cpointer_t)6);
    10. tb_vector_insert_tail(vector, (tb_cpointer_t)9);
    11.  
    12. /* 通过内置的tb_predicate_leq(<=)谓词函数,进行查找元素
    13. *
    14. * 目前的内置谓词有:
    15. * tb_predicate_le(<)
    16. * tb_predicate_eq(==)
    17. * tb_predicate_be(<)
    18. * tb_predicate_leq(<=)
    19. * tb_predicate_beq(>=)
    20. *
    21. * 当然你也可以自定义一个自己的谓词函数,只要满足如下原型就行了:
    22. * tb_bool_t (*tb_predicate_ref_t)(tb_iterator_ref_t iterator, tb_cpointer_t item, tb_cpointer_t value);
    23. *
    24. * 如果你看到算法名带有_if后缀,基本上都是可以传递谓词函数的,例如:
    25. * tb_find_all_if
    26. * tb_rfind_all_if
    27. * tb_count_if
    28. * tb_remove_if
    29. * tb_remove_first_if
    30. *
    31. * 注:
    32. * tb_binary_find_all_if 目前是不支持谓词的,但是可以指定一个自定义的比较器
    33. */
    34. tb_size_t itor = tb_find_all_if(vector, tb_predicate_leq, (tb_cpointer_t)5);
    35. if (itor != tb_iterator_tail(vector))
    36. {
    37. // 获取元素值:5
    38. tb_size_t value = tb_iterator_item(vector, itor);
    39. }
    40.  
    41. // 释放vector
    42. tb_vector_exit(vector);
    43. }

    原生的数组也是可以使用算法进行比较的,下面给个比较常用的查找例子

    注: 这里用了二分查找,因此不能使用谓词函数,只能使用比较器函数

    1. // 定义一个字符集操作的数据结构
    2. typedef struct __tb_charset_t
    3. {
    4. tb_size_t type;
    5. tb_char_t const* name;
    6. tb_long_t (*get)(tb_static_stream_ref_t sstream, tb_bool_t be, tb_uint32_t* ch);
    7. tb_long_t (*set)(tb_static_stream_ref_t sstream, tb_bool_t be, tb_uint32_t ch);
    8.  
    9. }tb_charset_t;
    10.  
    11. // 定义一个原生数组
    12. static tb_charset_t charsets[] =
    13. {
    14. {TB_CHARSET_TYPE_ASCII, "ascii", tb_charset_ascii_get, tb_charset_ascii_set }
    15. , {TB_CHARSET_TYPE_GB2312, "gb2312", tb_charset_gb2312_get, tb_charset_gb2312_set }
    16. , {TB_CHARSET_TYPE_GBK, "gbk", tb_charset_gb2312_get, tb_charset_gb2312_set }
    17. , {TB_CHARSET_TYPE_ISO8859, "iso8859", tb_charset_iso8859_get, tb_charset_iso8859_set }
    18. , {TB_CHARSET_TYPE_UCS2, "ucs3", tb_charset_ucs2_get, tb_charset_ucs2_set }
    19. , {TB_CHARSET_TYPE_UCS4, "ucs4", tb_charset_ucs4_get, tb_charset_ucs4_set }
    20. , {TB_CHARSET_TYPE_UTF16, "utf16", tb_charset_utf16_get, tb_charset_utf16_set }
    21. , {TB_CHARSET_TYPE_UTF32, "utf32", tb_charset_utf32_get, tb_charset_utf32_set }
    22. , {TB_CHARSET_TYPE_UTF8, "utf8", tb_charset_utf8_get, tb_charset_utf8_set }
    23. };
    24.  
    25. // 按名字查找比较函数
    26. static tb_long_t tb_charset_comp_by_name(tb_iterator_ref_t iterator, tb_cpointer_t item, tb_cpointer_t name)
    27. {
    28. return tb_stricmp(((tb_charset_ref_t)item)->name, (tb_char_t const*)name);
    29. }
    30.  
    31. // 将原生的数组,初始化成一个迭代器
    32. tb_array_iterator_t array_iterator;
    33. tb_iterator_ref_t iterator = tb_iterator_make_for_mem(&array_iterator, charsets, tb_arrayn(charsets), sizeof(tb_charset_t));
    34.  
    35. // 针对这个迭代器根据名字进行二分法查找
    36. tb_size_t itor = tb_binary_find_all_if(iterator, tb_charset_comp_by_name, "utf8");
    37.  
    38. // 如果找到
    39. if (itor != tb_iterator_tail(iterator))
    40. {
    41. // 获取元素对象
    42. tb_charset_t* charset = (tb_charset_t*)tb_iterator_item(iterator, itor);
    43. }

    注:上面的例子摘录自TBOX库内部的代码,仅供参考,不能直接copy使用。