zoukankan      html  css  js  c++  java
  • C语言实现静态链表

    分享一段代码,一个静态链表的C语言实现,其中包含着一种简单的内存管理策略:固定大小的链式管理。

    在动手之前我一直以为静态链表和动态链表没有什么差别,细细一想才发现,原来静态链表之中隐藏着一个非常值得讨论的话题——内存管理。

    静态链表的“静态”二字是指内存的来源为静态内存(通常用全局数组)。与动态链表不同,在静态链表中节点内存的申请与释放都需要自行维护,由于这里是链表,也很容易想到将空余的节点链接起来形成一个free_list,每次需要时从free_list头部取出一个节点,释放时再将节点加到头部,这样就能够非常容易的实现链表的其他操作。

      1 // 静态链表 的实现
      2 #include <stdio.h>
      3 
      4 #define MAXN 16 // capacity of list.
      5 typedef int element; // element type.
      6 
      7 // define boolean type:
      8 typedef int bool;
      9 #define true -1
     10 #define false 0
     11 
     12 #define NPTR -1 // null pointer definition. can not between 0 to MAXN-1.
     13 typedef int pointer;
     14 
     15 #define DEBUGVAL(x) printf("%s: %d\n", #x, (x)); // a macro for debug.
     16 
     17 struct __node
     18 {
     19     element data;
     20     pointer next;
     21 }SLList[MAXN];
     22 pointer ifree, idata;
     23 
     24 #define nextof(p) SLList[p].next
     25 #define dataof(p) SLList[p].data
     26 
     27 #define _alloc(d) ifree; dataof(ifree)=(d); ifree != NPTR ? ifree=nextof(ifree) : NPTR
     28 #define _free(p)  nextof(p)=ifree; ifree = p
     29 
     30 void init()
     31 {
     32     int i;
     33     ifree = 0;
     34     idata = NPTR;
     35     for( i=0; i < MAXN-1; i++) 
     36         nextof(i) = i+1;
     37     nextof(i) = NPTR;
     38 }
     39 
     40 // clear all nodes.
     41 void clear() { init(); }
     42 
     43 // push val to front.
     44 bool push_front(element val)
     45 {
     46     pointer tmp, np;
     47     if( ifree != NPTR ) {
     48         np = _alloc(val);
     49         nextof(np) = idata;
     50         idata = np;
     51         return true;
     52     }
     53     return false;
     54 }
     55 
     56 // push val to end of list.
     57 bool push_back(element val)
     58 {
     59     if( idata == NPTR ) { // 空表,直接写入
     60         idata = _alloc(val);
     61         nextof(idata) = NPTR;
     62         return true;
     63     }
     64     if( ifree != NPTR ) { // 非空,先找到最后一个节点
     65         pointer last = idata, np;
     66         while( nextof(last) != NPTR ) last = nextof(last);        
     67         np = _alloc(val);
     68         nextof(np) = NPTR;
     69         nextof(last) = np;
     70         return true;
     71     }
     72     return false;
     73 }
     74 
     75 // insert val to after p pointed node.
     76 bool insert_after(pointer p, element val)
     77 {
     78     if( ifree != NPTR && p != NPTR ) {
     79         pointer pn = _alloc(val);
     80         nextof(pn) = nextof(p);
     81         nextof(p)  = pn;        
     82         return true;
     83     }
     84     return false;
     85 }
     86 
     87 // insert to the position in front of p.
     88 bool insert(pointer ptr, element val)
     89 {
     90     if( ifree == NPTR ) return false;  // 没有结点,直接返回
     91     if( ptr == idata ) { // 有一个节点
     92         pointer np = _alloc(val);
     93         nextof(np) = idata;
     94         idata = np;    
     95         return true;
     96     }
     97     else { // 其他情况,先找 ptr 的前驱,再插入
     98         pointer p = idata;
     99         while(  p != NPTR ) {
    100             if( nextof(p) == ptr ) { // find p -- the prev node of ptr.
    101                 return insert_after(p, val); // insert val after p.            
    102             }
    103            p = nextof(p);
    104         }
    105     }
    106     return false;
    107 }
    108 
    109 // find element, return the prev node pointer.
    110 pointer find_prev(element val)
    111 {
    112     pointer p = idata;
    113     while(  p != NPTR ) {
    114         if( dataof( nextof(p) ) == val )
    115             return p;
    116         p = nextof(p);
    117     }
    118     return NPTR;
    119 }
    120 
    121 // find element, return the node  pointer.
    122 pointer find(element val)
    123 {
    124     pointer p = idata;
    125     while(  p != NPTR ) {
    126         if( dataof(p) == val ) return p;
    127         p = nextof(p);
    128     }
    129     return NPTR;
    130 }
    131 
    132 // pop front element.
    133 void pop_front()
    134 {
    135     if( idata != NPTR ) { // 将 data list 最前面的节点 移到 free list 上
    136 #if 0
    137         pointer p = idata;        
    138         idata = nextof(idata); // idata = nextof(idata);
    139         nextof(p) = ifree;  // SLList[p].next = ifree;
    140         ifree = p; 
    141 #else
    142         pointer p = idata;
    143         idata = nextof(idata);
    144         _free(p);
    145 #endif
    146     }
    147 }
    148 
    149 // pop back element.
    150 void pop_back()
    151 {
    152     if( idata == NPTR ) return;
    153     if( nextof(idata) == NPTR ) { // only 1 node.
    154         nextof(idata) = ifree;
    155         ifree = idata;
    156         idata = NPTR;
    157     }
    158     else { // 找到最后一个节点 p,以及它的前驱 q.
    159         // TODO: find the last node p, and it's perv node q. 
    160         pointer p = idata, q; 
    161         while( nextof(p) != NPTR ) {
    162             q = p;
    163             p = nextof( p );
    164         }
    165         // remove *p to free list, update nextof(q) to NPTR.
    166         nextof(p) = ifree;
    167         ifree = p;
    168         nextof(q) = NPTR;
    169     }
    170 }
    171 
    172 void show()
    173 {
    174     pointer p = idata;
    175     for( ; p != NPTR; p = nextof(p) ) {
    176         printf(" %3d ", dataof(p) );
    177     }
    178     printf("\n");
    179 }
    180 
    181 #define INFOSHOW
    182 void info()
    183 {
    184 #ifdef INFOSHOW
    185     int i;    
    186     DEBUGVAL(ifree);
    187     DEBUGVAL(idata);
    188     puts("====================\n"
    189         "index\tdata\tnext\n"
    190         "--------------------");
    191     for(i=0; i<MAXN; i++) {
    192         printf("%d\t%d\t%d\n", i, SLList[i].data, SLList[i].next);
    193     }
    194     puts("====================\n");
    195 #endif
    196 }
    197 
    198 /*
    199     测试程序:
    200 */
    201 int main()
    202 {
    203     int i;
    204     init();
    205 
    206 #if 1  // push_front test:
    207     puts("push_front test:");
    208     for(i=0; i<MAXN+2; i++)    {
    209         push_front(2*i+1);
    210         show();    
    211     }
    212     
    213     puts("pop_front test:");
    214     for(i=0; i<MAXN+2; i++)    {
    215         pop_front();
    216         show();
    217     }
    218 #endif
    219 
    220 #if 1 // push_back test:
    221     puts("push_back test:");
    222     for(i=0; i<MAXN+2; i++)    {
    223         push_back((i+1)*10);
    224         show();    
    225     }
    226 
    227     puts("pop_back test:");
    228     for(i=0; i<MAXN+1; i++)
    229     {
    230         pop_back();
    231         show();
    232     }
    233 #endif
    234     
    235 #if 1 // insert test:
    236     puts("insert test:");
    237     for(i=0; i<MAXN+2; i++)
    238     {
    239         insert(idata, (i+1)*10);
    240         show();
    241     }
    242     puts("clear...\n");
    243     clear();
    244 #endif
    245 
    246 #if 1 // insert_after test:
    247     puts("insert_after test:");
    248     push_back(-99);
    249     for(i=0; i<MAXN+1; i++) {
    250         insert_after(idata, i+1);
    251         show();
    252     }
    253     puts("clear...\n");
    254     clear();
    255 #endif
    256     
    257 #if 1 // find test:
    258     puts("find test:");
    259     for(i=0; i<MAXN/2; i++) {
    260         push_front(MAXN-i);
    261         push_back(MAXN/2-i);
    262         //show();
    263     }
    264     show();
    265     info();
    266     for(i=0; i<MAXN; i++) {
    267         int val = rand()%(2*MAXN);
    268         pointer p = find(val);
    269         if( p != NPTR )
    270             printf("%3d %3d found at %d\n", val, dataof(p), p);
    271         else
    272             printf("%3d not found\n", val);
    273     }
    274 #endif
    275 
    276 #if 1
    277     puts("\nfind_prev test:");
    278     for(i=0; i<MAXN; i++) {
    279         int val = rand()%(2*MAXN);
    280         pointer p = find_prev(val);
    281         if( p != NPTR )
    282             printf("%3d %3d found at %d's next.\n", val, dataof(nextof(p)), p);
    283         else
    284             printf("%3d not found\n", val);
    285     }
    286 #endif 
    287 
    288 #if 1 // find_prev and insert_after test:
    289     clear();
    290     puts("\nfind_prev and insert_after test:");
    291     for(i=0; i<MAXN/2; i++)    {
    292         push_front(MAXN/2-i);
    293     }
    294     show();
    295     for(i=0; i<MAXN/2; i++) {
    296         int val = rand()%(2*MAXN), n=-(i+1);
    297         pointer p = find_prev(val);
    298         if( p != NPTR ) {
    299             printf("insert %d to front of %d:", n, val);
    300             insert_after(p, n);
    301             show();
    302         }
    303     }    
    304 #endif    
    305 
    306 #if 1 // find and insert test:
    307     clear();
    308     puts("\nfind and insert test:");
    309     for(i=0; i<MAXN/2; i++)    {
    310         push_front(MAXN/2-i);
    311     }
    312     show();
    313         for(i=0; i<MAXN/2; i++) {
    314         int val = rand()%MAXN, n=-(i+1);
    315         pointer p = find(val);
    316         if( p != NPTR ) {
    317             printf("insert %d to after of %d:", n, val);
    318             insert_after(p, n);
    319             show();
    320         }
    321     }
    322 #endif
    323     
    324     puts("end of main().");    
    325     return 0;
    326 }
    327 
    328 // 

    测试结果如下:

    push_front test:
       1 
       3    1 
       5    3    1 
       7    5    3    1 
       9    7    5    3    1 
      11    9    7    5    3    1 
      13   11    9    7    5    3    1 
      15   13   11    9    7    5    3    1 
      17   15   13   11    9    7    5    3    1 
      19   17   15   13   11    9    7    5    3    1 
      21   19   17   15   13   11    9    7    5    3    1 
      23   21   19   17   15   13   11    9    7    5    3    1 
      25   23   21   19   17   15   13   11    9    7    5    3    1 
      27   25   23   21   19   17   15   13   11    9    7    5    3    1 
      29   27   25   23   21   19   17   15   13   11    9    7    5    3    1 
      31   29   27   25   23   21   19   17   15   13   11    9    7    5    3    1 
      31   29   27   25   23   21   19   17   15   13   11    9    7    5    3    1 
      31   29   27   25   23   21   19   17   15   13   11    9    7    5    3    1 
    pop_front test:
      29   27   25   23   21   19   17   15   13   11    9    7    5    3    1 
      27   25   23   21   19   17   15   13   11    9    7    5    3    1 
      25   23   21   19   17   15   13   11    9    7    5    3    1 
      23   21   19   17   15   13   11    9    7    5    3    1 
      21   19   17   15   13   11    9    7    5    3    1 
      19   17   15   13   11    9    7    5    3    1 
      17   15   13   11    9    7    5    3    1 
      15   13   11    9    7    5    3    1 
      13   11    9    7    5    3    1 
      11    9    7    5    3    1 
       9    7    5    3    1 
       7    5    3    1 
       5    3    1 
       3    1 
       1 
    
    
    
    push_back test:
      10 
      10   20 
      10   20   30 
      10   20   30   40 
      10   20   30   40   50 
      10   20   30   40   50   60 
      10   20   30   40   50   60   70 
      10   20   30   40   50   60   70   80 
      10   20   30   40   50   60   70   80   90 
      10   20   30   40   50   60   70   80   90  100 
      10   20   30   40   50   60   70   80   90  100  110 
      10   20   30   40   50   60   70   80   90  100  110  120 
      10   20   30   40   50   60   70   80   90  100  110  120  130 
      10   20   30   40   50   60   70   80   90  100  110  120  130  140 
      10   20   30   40   50   60   70   80   90  100  110  120  130  140  150 
      10   20   30   40   50   60   70   80   90  100  110  120  130  140  150  160 
      10   20   30   40   50   60   70   80   90  100  110  120  130  140  150  160 
      10   20   30   40   50   60   70   80   90  100  110  120  130  140  150  160 
    pop_back test:
      10   20   30   40   50   60   70   80   90  100  110  120  130  140  150 
      10   20   30   40   50   60   70   80   90  100  110  120  130  140 
      10   20   30   40   50   60   70   80   90  100  110  120  130 
      10   20   30   40   50   60   70   80   90  100  110  120 
      10   20   30   40   50   60   70   80   90  100  110 
      10   20   30   40   50   60   70   80   90  100 
      10   20   30   40   50   60   70   80   90 
      10   20   30   40   50   60   70   80 
      10   20   30   40   50   60   70 
      10   20   30   40   50   60 
      10   20   30   40   50 
      10   20   30   40 
      10   20   30 
      10   20 
      10 
    
    
    insert test:
      10 
      20   10 
      30   20   10 
      40   30   20   10 
      50   40   30   20   10 
      60   50   40   30   20   10 
      70   60   50   40   30   20   10 
      80   70   60   50   40   30   20   10 
      90   80   70   60   50   40   30   20   10 
     100   90   80   70   60   50   40   30   20   10 
     110  100   90   80   70   60   50   40   30   20   10 
     120  110  100   90   80   70   60   50   40   30   20   10 
     130  120  110  100   90   80   70   60   50   40   30   20   10 
     140  130  120  110  100   90   80   70   60   50   40   30   20   10 
     150  140  130  120  110  100   90   80   70   60   50   40   30   20   10 
     160  150  140  130  120  110  100   90   80   70   60   50   40   30   20   10 
     160  150  140  130  120  110  100   90   80   70   60   50   40   30   20   10 
     160  150  140  130  120  110  100   90   80   70   60   50   40   30   20   10 
    clear...
    
    insert_after test:
     -99    1 
     -99    2    1 
     -99    3    2    1 
     -99    4    3    2    1 
     -99    5    4    3    2    1 
     -99    6    5    4    3    2    1 
     -99    7    6    5    4    3    2    1 
     -99    8    7    6    5    4    3    2    1 
     -99    9    8    7    6    5    4    3    2    1 
     -99   10    9    8    7    6    5    4    3    2    1 
     -99   11   10    9    8    7    6    5    4    3    2    1 
     -99   12   11   10    9    8    7    6    5    4    3    2    1 
     -99   13   12   11   10    9    8    7    6    5    4    3    2    1 
     -99   14   13   12   11   10    9    8    7    6    5    4    3    2    1 
     -99   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1 
     -99   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1 
     -99   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1 
    clear...
    
    find test:
       9   10   11   12   13   14   15   16    8    7    6    5    4    3    2    1 
    ifree: -1
    idata: 14
    ====================
    index    data    next
    --------------------
    0    16    1
    1    8    3
    2    15    0
    3    7    5
    4    14    2
    5    6    7
    6    13    4
    7    5    9
    8    12    6
    9    4    11
    10    11    8
    11    3    13
    12    10    10
    13    2    15
    14    9    12
    15    1    -1
    ====================
    
      9   9 found at 14
      3   3 found at 11
     30 not found
      4   4 found at 9
      1   1 found at 15
     12  12 found at 8
     22 not found
     14  14 found at 4
     18 not found
     16  16 found at 0
      9   9 found at 14
     17 not found
     17 not found
     27 not found
      9   9 found at 14
     11  11 found at 10
    
    find_prev test:
     19 not found
      6   6 found at 3's next.
     27 not found
     28 not found
      7   7 found at 1's next.
     12  12 found at 10's next.
     30 not found
     25 not found
      4   4 found at 7's next.
     30 not found
     13  13 found at 8's next.
     28 not found
      6   6 found at 3's next.
     23 not found
      7   7 found at 1's next.
     30 not found
    
    find_prev and insert_after test:
       1    2    3    4    5    6    7    8 
    insert -4 to front of 8:   1    2    3    4    5    6    7   -4    8 
    insert -5 to front of 3:   1    2   -5    3    4    5    6    7   -4    8 
    insert -8 to front of 6:   1    2   -5    3    4    5   -8    6    7   -4    8 
    
    find and insert test:
       1    2    3    4    5    6    7    8 
    insert -2 to after of 3:   1    2    3   -2    4    5    6    7    8 
    insert -6 to after of 8:   1    2    3   -2    4    5    6    7    8   -6 
    insert -7 to after of 5:   1    2    3   -2    4    5   -7    6    7    8   -6 
    end of main().
  • 相关阅读:
    Android基于mAppWidget实现手绘地图(五)--如何创建地图资源
    Android基于mAppWidget实现手绘地图(四)--如何附加javadoc
    Android基于mAppWidget实现手绘地图(三)--环境搭建
    Android基于mAppWidget实现手绘地图(二)--概要
    Android基于mAppWidget实现手绘地图(一)--简介
    网络通信之Socket与LocalSocket的比较
    Python-Django 整合Django和jquery-easyui
    Python-Django 第一个Django app
    RobotFramework 官方demo Quick Start Guide rst配置文件分析
    RobotFramework RobotFramework官方demo Quick Start Guide浅析
  • 原文地址:https://www.cnblogs.com/xusw/p/2964465.html
Copyright © 2011-2022 走看看