[应用相关] 自己造轮子系列 : 链表

[复制链接]
 楼主| shen520 发表于 2023-2-8 17:24 | 显示全部楼层 |阅读模式
本帖最后由 shen520 于 2023-2-8 17:26 编辑
  1. #ifndef SYS_LIST_H
  2. #define SYS_LIST_H

  3. #include        "stdint.h"
  4. #include        "string.h"

  5. #define list_entry(ptr, type, member)   \
  6.     ( ( type * ) ( ( char * ) ( ptr ) - ( size_t ) ( & ( ( type * ) 0 )->member ) ) )

  7. #define list_zero(ptr)                  \
  8.     memset ( ptr, 0, sizeof ( struct list_node_t ) )

  9. /*  
  10.     struct demo_t
  11.     {
  12.         struct list_node_t  node ;
  13.     } ;

  14.     struct demo_t demo ;
  15.     list_zero ( & demo.node ) ;

  16.     void callback ( struct list_node_t * list )
  17.     {
  18.         struct demo_t * demo = list_entry ( list  , struct demo_t  , node ) ;
  19.     }
  20. */

  21. struct list_obj_t ;

  22. struct list_node_t
  23. {
  24.     struct list_node_t  * prev ;
  25.     struct list_node_t  * next ;
  26. } ;

  27. void list_initialize ( void * ( * malloc ) ( size_t size ), void ( * free ) ( void * p ) ) ;

  28. struct list_obj_t * list_create ( void ) ;
  29. void list_insert ( struct list_obj_t * obj, struct list_node_t * list ) ;
  30. void list_delete ( struct list_obj_t * obj, struct list_node_t * list ) ;
  31. int  list_number ( struct list_obj_t * obj ) ;
  32. void list_poll ( struct list_obj_t * obj,  void ( * callback ) ( struct list_node_t * list ) ) ;
  33. void list_printf ( struct list_obj_t * obj ) ;
  34. void list_destory ( struct list_obj_t * obj ) ;

  35. #endif

  1. #include        "list.h"
  2. #include        "stdlib.h"
  3. #include        "stdio.h"
  4. #include        "string.h"

  5. struct list_driver_t {
  6.     void * ( * malloc ) ( size_t size ) ;
  7.     void ( * free ) ( void * p ) ;
  8. } ;

  9. struct list_obj_t {
  10.     struct list_node_t  node ;
  11. } ;

  12. static struct list_driver_t driver = { malloc, free } ;

  13. void list_initialize ( void * ( * malloc ) ( size_t size ), void ( * free ) ( void * p ) ) {
  14.     driver.malloc = malloc ;
  15.     driver.free = free ;
  16. }

  17. struct list_obj_t * list_create ( void ) {
  18.     struct list_obj_t       * obj ;

  19.     obj = ( struct list_obj_t * ) driver.malloc ( sizeof ( struct list_obj_t ) ) ;
  20.     list_zero ( & obj->node ) ;

  21.     return obj ;
  22. }

  23. void list_destory ( struct list_obj_t * obj ) {
  24.     driver.free ( obj ) ;
  25. }

  26. void list_insert ( struct list_obj_t  * obj, struct list_node_t * list ) {
  27.     struct list_node_t      * curr = & obj->node ;

  28.     while ( curr->next ) {
  29.         if ( curr == list ) {
  30.             return ;
  31.         }
  32.         curr = curr->next ;
  33.     }

  34.     curr->next = list ;
  35.     list->prev = curr ;
  36. }

  37. int  list_number ( struct list_obj_t * obj ) {
  38.     struct list_node_t      * curr = & obj->node ;
  39.     int                     cnt = 0 ;

  40.     do {
  41.         if ( curr->prev ) {
  42.             cnt += 1 ;
  43.         }
  44.         curr = curr->next ;
  45.     } while ( curr ) ;

  46.     return cnt ;
  47. }

  48. void list_delete ( struct list_obj_t * obj,  struct list_node_t * list ) {
  49.     struct list_node_t      * curr = & obj->node ;

  50.     do {
  51.         if ( curr == list ) {
  52.             list->prev->next = list->next ;
  53.             if ( list->next ) {
  54.                 list->next->prev = list->prev ;
  55.             }
  56.             break ;
  57.         }

  58.         curr = curr->next ;
  59.     } while ( curr ) ;
  60. }


  61. void list_poll ( struct list_obj_t * obj, void ( * callback ) ( struct list_node_t * list ) ) {
  62.     struct list_node_t      * curr = & obj->node ;

  63.     do {
  64.         if ( curr->prev ) {
  65.             callback ( curr ) ;
  66.         }
  67.         curr = curr->next ;
  68.     } while ( curr ) ;
  69. }

  70. void list_printf ( struct list_obj_t  * obj ) {
  71.     struct list_node_t      * curr = & obj->node ;
  72.     int                     cnt = 0 ;

  73.     do {

  74.         printf ( "    %2d - node %08x : prev %08x , next %08x \r\n", cnt, curr, curr->prev, curr->next ) ;
  75.         cnt ++ ;
  76.         curr = curr->next ;
  77.     } while ( curr ) ;
  78. }



朝生 发表于 2023-2-9 13:42 | 显示全部楼层
链表刚开始学的时候总是搞不懂,接触的多了也就会了。
V853 发表于 2023-2-9 13:43 | 显示全部楼层
链表网上例程挺多的,自己能实现一个也挺不错的。
芯路例程 发表于 2023-2-9 13:43 | 显示全部楼层
当初面试也会问的一个问题,因为链表主要考C指针操作。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

24

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部