美文网首页
[习题33]链表算法:冒泡排序、归并排序(单元测试)

[习题33]链表算法:冒泡排序、归并排序(单元测试)

作者: AkuRinbu | 来源:发表于2019-01-03 17:14 被阅读12次

    使用教材

    《“笨办法” 学C语言(Learn C The Hard Way)》
    https://www.jianshu.com/p/b0631208a794

    • 完整源码 : liblcthw

    https://github.com/zedshaw/liblcthw

    作者原话

    链表用于排序时很糟糕的,如果必须要排序,我们有别的更好的数据结构可用。之所以要将这两种算法, 是因为使用链表实现它们略微有点儿难度,而且还可以让你思考如何更加有效地进行链表操作。

    工作顺序

    首先,布置文件 list_algos.hlist_algos.clist_algos_tests.c

    • 1、查看文件结构,注意三个新增文件的位置
    liblcthw$ ls -R
    .:
    bin  LICENSE  Makefile  README.md  src  tests
    
    ./bin:
    
    ./src:
    lcthw
    
    ./src/lcthw:
    dbg.h  list_algos.c  list_algos.h  list.c  list.h
    
    ./tests:
    list_algos_tests.c  list_tests.c  minunit.h  runtests.sh
    
    
    • 2、运行 make 命令,warning不用在意,使编译通过
    • 3、再次查看文件结构 ls -R

    然后 ,参考书上提供的步骤

    [1] 打开 wiki 的页面,例如:冒泡排序(bubble sort)
    [2] 阅读算法描述,观察图例
    [3] 在纸上画出大致算法排序过程
    [4] 回到wiki页面,复制、粘贴 “伪代码”(非C代码)到`list_algos.c`的冒泡函数里
    [5] 把 伪代码 翻译成 C代码
    [6] 使用单元测试来保证函数正常工作
    [7] 重复步骤[5]~[6] 直到测试通过
    [8] 添加更多测试,用来检测边缘情况,例如:空链表、已经排序过的链表等
    [9] 实在做不出来可以“作弊”,看liblcthw库里的代码
    

    排序算法

    • 冒泡排序

    https://en.wikipedia.org/wiki/Bubble_sort

    • 归并排序

    https://en.wikipedia.org/wiki/Merge_sort

    输出结果

    anno-m:~/Desktop/liblcthw$ make
    cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/list_algos.o src/lcthw/list_algos.c
    cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/list.o src/lcthw/list.c
    ar rcs build/liblcthw.a src/lcthw/list_algos.o src/lcthw/list.o
    ranlib build/liblcthw.a
    cc -shared -o build/liblcthw.so src/lcthw/list_algos.o src/lcthw/list.o
    cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG     tests/list_algos_tests.c  -ldl build/liblcthw.a -o tests/list_algos_tests
    
    cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG     tests/list_tests.c  -ldl build/liblcthw.a -o tests/list_tests
    
    sh ./tests/runtests.sh
    Running unit tests:
    ----
    RUNNING: ./tests/list_algos_tests
    ALL TESTS PASSED
    Tests run: 2
    tests/list_algos_tests PASS
    ----
    RUNNING: ./tests/list_tests
    ALL TESTS PASSED
    Tests run: 6
    tests/list_tests PASS
    

    源码说明

    1、对回调函数的运用

    • 算法头文件 list_algos.h
    typedef int (*List_compare) (const void *a, const void *b);
    
    • 算法实现文件 list_algos.c
    int List_bubble_sort(List * list, List_compare cmp)
    {
      // . . . 
          if (cmp(cur->value, cur->next->value) > 0) {
     // . . .
    }
    
    • 单元测试文件 list_algos_tests.c
    char *test_bubble_sort()
    {
    // . . . 
        int rc = List_bubble_sort(words, (List_compare) strcmp);
    // . . .
    }
    
    • 这样一来,通过在单元测试里写上strcmp,算法实现里就会解读成strcmp(cur->value, cur->next->value)

    strcmp

    • 定义于头文件 <string.h>
    • int strcmp( const char *lhs, const char *rhs );

    返回值
    若字典序中 lhs 先出现于 rhs 则为负值。
    若 lhs 与 rhs 比较相等则为零。
    若字典序中 lhs 后出现于 rhs 则为正值。

    2、如何实现结点互换?

    • 直接交换结点的value,而不去更改结点的prev以及next链接;
    /*****    list_algos.c    *****/
    inline void ListNode_swap(ListNode * a, ListNode * b)
    {
        void *temp = a->value;
        a->value = b->value;
        b->value = temp;
    }
    
    /*****     list.h    *****/
    typedef struct ListNode {
        struct ListNode *next;
        struct ListNode *prev;
        void *value;
    } ListNode;
    
    

    相关文章

      网友评论

          本文标题:[习题33]链表算法:冒泡排序、归并排序(单元测试)

          本文链接:https://www.haomeiwen.com/subject/nrwfrqtx.html

          热点阅读