分享

一步一步写算法(之线性结构的处理)

 qdhtxxlhz 2011-11-23

    我们知道,在内存中的空间都是连续的。也就是说,0x00000001下面的地址必然是0x00000002。所以,空间上是不会出现地址的突变的。那什么数据结构类型是连续内部空间呢,其实就是数组,当然也可以是堆。数组有很多优势,它可以在一段连续空间内保存相同类型的数据,并且对这些数据进行管理。所以从这个意义上说,掌握了数组才能说明你数据结构入门了。

    那么,在实际开发中,我们对线性结构应该注意些什么呢?我个人的观点:

    (1)数组的资源是有限的,必须确定资源的范围

    (2)数组中资源的申请和释放必须一一对应,否则很容易造成资源泄漏的现象

    (3)数组中的注意事项同样应用于堆分配的连续内存资源空间中

    下面是自己设计的一个int分配的小程序,大家可以一起尝试一下:

    a)设计内存节点的数据形式

  1. typedef struct _DATA_NODE  
  2. {  
  3.     int* pData;  
  4.     char* pFlag;  
  5.     int num;  
  6. }DATA_NODE;  
  7.   
  8. #define STATUS int   
  9. #define TRUE 1   
  10. #define FALSE 0  
    b)创建内存节点

  1. DATA_NODE* malloc_node(int number)  
  2. {  
  3.     DATA_NODE* pDataNode = NULL;  
  4.     if(0 == number)  
  5.         return NULL;  
  6.   
  7.     pDataNode = (DATA_NODE*) malloc(sizeof(DATA_NODE));  
  8.     assert(NULL != pDataNode);  
  9.     memset(pDataNode, 0, sizeof(DATA_NODE));  
  10.   
  11.     pDataNode->pData = (int*)malloc(sizeof(int) * number);  
  12.     if(NULL == pDataNode->pData){  
  13.         free(pDataNode);  
  14.         return NULL;  
  15.     }  
  16.   
  17.     pDataNode->pFlag = (char*) malloc( (number + 7) >> 3);  
  18.     if(NULL == pDataNode->pFlag){  
  19.         free(pDataNode->pData);  
  20.         free(pDataNode);  
  21.         return NULL;  
  22.     }  
  23.   
  24.     memset(pDataNode->pData, 0, sizeof(int) * number);  
  25.     memset(pDataNode->pFlag, 0, (number + 7) >> 3);  
  26.     pDataNode->num = number;  
  27.     return pDataNode;  
  28. }  
    c) 删除内存节点

  1. STATUS free_node(const DATA_NODE* pDataNode)  
  2. {  
  3.     if(NULL == pDataNode)  
  4.         return FALSE;  
  5.   
  6.     assert(NULL != pDataNode ->pData);  
  7.     assert(NULL != pDataNode-> pFlag);  
  8.     assert(0 != pDataNode);  
  9.   
  10.     free(pDataNode->pFlag);  
  11.     free(pDataNode->pData);  
  12.     free((void*)pDataNode);  
  13.     return TRUE;  
  14. }  
    d)判断当前是否还有内存可以分配

  1. int check_if_data_exist(const DATA_NODE* pDataNode)  
  2. {  
  3.     int number = pDataNode->num;  
  4.     char* pFlag = pDataNode->pFlag;  
  5.     unsigned char flag = 0;  
  6.     int loop = 1;  
  7.   
  8.     while(loop <= number){  
  9.         flag = pFlag[(loop + 7) >> 3 - 1] & (0x1 << ((loop + 7) % 8));  
  10.         if(0 != flag){  
  11.             return loop;  
  12.         }  
  13.   
  14.         loop ++;  
  15.     }  
  16.   
  17.     return -1;  
  18. }  
    e) 分配内存空间

  1. int* alloca_data(const DATA_NODE* pDataNode)  
  2. {  
  3.     int* pData = NULL;  
  4.     int pos;  
  5.     if(NULL == pDataNode)  
  6.         return NULL;  
  7.   
  8.     if(-1 == (pos = check_if_data_exist(pDataNode)))  
  9.         return NULL;  
  10.   
  11.   
  12.     pDataNode->pFlag[(pos + 7) >> 3 - 1] |= 0x1 << ((pos + 7)% 8);  
  13.     return pDataNode->pData + (pos - 1);  
  14. }  
    f)回收内存空间

  1. STATUS free_data(const DATA_NODE* pDataNode, const int* pData)  
  2. {  
  3.     int pos = 0;  
  4.     if(NULL == pDataNode || NULL == pData)  
  5.         return FALSE;  
  6.   
  7.     if(pData < pDataNode->pData || pData > (pDataNode->pData + pDataNode->num))  
  8.         return FALSE;  
  9.   
  10.     pos = (pData - pDataNode->pData) >> 3;  
  11.     pDataNode->pFlag[(pos + 7) -1]  &= ~(0x1 << ((pos + 7) % 8));  
  12.     return TRUE;  
  13. }  
    g)统计当前已经分配了多少DWORD空间
  1. int count_free_space(const DATA_NODE* pDataNode)  
  2. {  
  3.     int count = 0;  
  4.     int loop = 1;  
  5.     char flag = 0;  
  6.     if(NULL == pDataNode)  
  7.         return 0;  
  8.   
  9.     for(; loop <= pDataNode->num; loop++)  
  10.     {  
  11.         flag = pDataNode->pFlag[(loop + 7) >> 3 - 1] & (0x1 << ((loop + 7) % 8));  
  12.         if(0 == flag){  
  13.             count ++;  
  14.         }  
  15.     }  
  16.       
  17.     return count;  
  18. }  

   上面的代码只是一个示范,大家可以在这个基础之上加以改进,比如说:

    (1)修改成可以自由分配很多内存,注意需要同时修改flag的结构类型

    (2)修改成先到先得的内存分配类型

    (3)修改成最合适空间的内存分配类型

    (4)修改成debug类型的内存分配形式,每次分配和释放的时候都检查内存是否越界、是否没有成对运行,注意需要添加对应的判断函数 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多