链表排序
uthash版本 :2.0.2
作者:jafon.tian
转载请注明出处:https://blog.csdn.net/JT_Notes
排序API宏
uthash提供了宏用于hash表中元素的排序
API名称 | 参数与说明 |
---|---|
HASH_SORT | (head,cmpfcn) head:hash表头;cmpfcn:元素比较函数 |
排序算法
uthash采用了分治算法,算法复杂度为O(n log(n))。算法的基本原理是递归,每一次递归都将输入链表当成是规模小一些的有序链表的连接组合。排序过程会遍历log(n)次整个链表,每次遍历都会将相邻的两个有序链表组成一个有序链表,最后就产生了一个完整的有序链表。
HASH_SORT的实现的妙处在于并未使用递归调用,而是反其道行之,从只包含一个元素的有序链表开始,生成包含两个元素的有序链表,然后生成包含四个元素的有序链表,最后得到整个有序链表。
下面是排序源码,为了能直观看出每次排序的变化,进行了一点调整,再输入参数中增加了pfcn打印函数,每次排序结束都会将链表头作为参数传给pfcn。
#define HASH_SORT_P(head, cmpfcn, pfcn) HASH_SRT_P(hh, head, cmpfcn, pfcn)
#define HASH_SRT_P(hh, head, cmpfcn, pfcn) \
do \
{ \
unsigned _hs_i; \
unsigned _hs_looping, _hs_nmerges, _hs_insize, _hs_psize, _hs_qsize; \
struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
if (head != NULL) \
{ \
_hs_insize = 1; \
_hs_looping = 1; \
_hs_list = &((head)->hh); \
while (_hs_looping != 0U) \
{ \
_hs_p = _hs_list; \
_hs_list = NULL; \
_hs_tail = NULL; \
_hs_nmerges = 0; \
while (_hs_p != NULL) \
{ \
_hs_nmerges++; \
_hs_q = _hs_p; \
_hs_psize = 0; \
for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) \
{ \
_hs_psize++; \
_hs_q = ((_hs_q->next != NULL) ? HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \
if (_hs_q == NULL) \
{ \
break; \
} \
} \
_hs_qsize = _hs_insize; \
while (