C语言的那些小秘密之链表(二)

发表于:2011-12-14 09:38

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:bigloomy(CSDNblog)    来源:51Testing软件测试网采编

分享:

  可能有的读者认为上面得代码有点复杂化了,其实不然,我们仅仅是写出了我们要讲解的双链表实现中最简单的部分,其实现的功能是创建一个链表,在链表末端添加结点,然后打印出链表中结点里存放的数据项,对代码的总体动能有了一个大概的了解之后,现在我们来逐一分析代码,为接下来添加功能模块打开思路。

  从main()函数开始,通过 DList* dlist = dlist_head_create();我们创建了一个头节点。值得注意的是,为了链表更加通用和符合实际需求,我们在此创建的链表存放的是结构,因为现实中在使用链表时,绝大部分都是存放结构的,而前一篇文章中我们创建单链表时我们存放的是数据,所以这一点读者是要引起注意的,接下来是一个for循环语句,在for循环语句中我们首先使用DStu* stu =(DStu*) malloc(sizeof(DStu));为stu分配了空间,这也是很多读者的一个易错点,不分配就使用下面的stu->score = i;语句,从而导致出错,如果读者对于指针还不是很了解的话可以看看我前面的文章《C语言的那些小秘密之指针》,在往下看dlist_append(dlist, (void*)stu);语句,从函数名称我们也可以看出它的功能是在链表的末端添加结点的,在函数里面我们使用了一个if判断语句来看分配的结点是否成功,如果成功继续往下执行,如果失败则返回DLIST_RETURN_FAIL。对于第一次分配的节点我们使用了 thiz->head = node;语句使其变为头结点,在第二次调用dlist_append(dlist, (void*)stu)函数分配结点之后,由于头结点已经不再为空,那么跳过if(thiz->head == NULL)语句,执行以下语句:

cursor = thiz->head;
while(cursor != NULL && cursor->next != NULL)
 {  cursor = cursor->next; }

  其功能为查找末端结点,然后使用 cursor->next = node; node->prev = cursor;语句来将刚刚创建的新结点node作为尾结点。main()函数中的for循环语句执行完之后就轮到了调用dlist_print(dlist, print_int)函数打印我们创建的双向链表保存的数据值了,在这里的时候我们用了前面我博客中提到的函数指针作为参数的使用,如果有对函数指针不熟悉的读者可以参考我之前写的一篇博客《C语言的那些小秘密之函数指针》,到此读者应该都理解了上面的代码,但是其中有个值得注意的地方,那就是main()函数中使用dlist_append(dlist, (void*)stu);的时候,我们传递的是一个无类型的指针,在创建新结点的时候,我们使用了一句node->data =(DStu*)data;进行一个强制转换,使得链表中的数据域指向的就是我们使用DStu* stu =(DStu*) malloc(sizeof(DStu));所创建的空间。创建了空间之后当然要释放掉,所以接下来我们就添加一个释放功能模块。新添加的代码我们用红色部分来标记。以便于读者的阅读

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. typedef enum _DListReturn  
  5. {  
  6.     DLIST_RETURN_OK,  
  7.     DLIST_RETURN_FAIL  
  8. }DListReturn;  
  9.   
  10. typedef struct _DStu  
  11. {  
  12.     int score;  
  13. }DStu;  
  14.   
  15. typedef struct _DListNode  
  16. {  
  17.     struct _DListNode* prev;  
  18.     struct _DListNode* next;  
  19.   
  20.     DStu* data;  
  21.   
  22. }DListNode;  
  23.   
  24. typedef struct _DList  
  25. {  
  26.     DListNode* head;  
  27. }DList;  
  28.   
  29. typedef DListReturn (*DListPrintFunction)(void* data);  
  30.   
  31. DListNode* dlist_node_create(void* data)  
  32. {  
  33.     DListNode* node;  
  34.     if((node = (DListNode*) malloc(sizeof(DListNode)))==NULL)  
  35.     {  
  36.         printf("分配空间失败!");  
  37.         exit(0);  
  38.     }  
  39.   
  40.     if(node != NULL)  
  41.     {  
  42.         node->prev = NULL;  
  43.         node->next = NULL;  
  44.         node->data =(DStu*)data;  
  45.     }  
  46.   
  47.     return node;  
  48. }  
  49.   
  50. DList* dlist_head_create(void)  
  51. {  
  52.     DList* thiz;  
  53.     if((thiz = (DList*)malloc(sizeof(DList)))==NULL)  
  54.     {  
  55.         printf("分配空间失败!");  
  56.         exit(0);  
  57.     }  
  58.   
  59.     if(thiz != NULL)  
  60.     {  
  61.         thiz->head = NULL;  
  62.     }  
  63.   
  64.     return thiz;  
  65. }  
  66.   
  67. DListReturn dlist_append(DList* thiz, void* data)  
  68. {  
  69.     DListNode* node = NULL;  
  70.     DListNode* cursor = NULL;  
  71.   
  72.     if((node = dlist_node_create(data)) == NULL)  
  73.     {  
  74.         return DLIST_RETURN_FAIL;   
  75.     }  
  76.   
  77.     if(thiz->head == NULL)  
  78.     {  
  79.         thiz->head = node;  
  80.   
  81.         return DLIST_RETURN_OK;  
  82.     }  
  83.   
  84.     cursor = thiz->head;  
  85.     while(cursor != NULL && cursor->next != NULL)  
  86.     {  
  87.         cursorcursor = cursor->next;  
  88.     }  
  89.   
  90.     cursor->next = node;  
  91.     node->prev = cursor;  
  92.   
  93.     return DLIST_RETURN_OK;  
  94. }  
  95.   
  96. DListReturn dlist_prepend(DList* thiz, void* data)  
  97. {  
  98.     DListNode* node = NULL;  
  99.     DListNode* cursor = NULL;  
  100.   
  101.     if((node = dlist_node_create(data)) == NULL)  
  102.     {  
  103.         return DLIST_RETURN_FAIL;   
  104.     }  
  105.   
  106.     if(thiz->head == NULL)  
  107.     {  
  108.         thiz->head = node;  
  109.   
  110.         return DLIST_RETURN_OK;  
  111.     }  
  112.   
  113.     cursor = thiz->head;  
  114.   
  115.     if(thiz->head == cursor)  
  116.         thiz->head = node;  
  117.   
  118.     node->next = cursor;  
  119.     cursor->prev = node;  
  120.   
  121.     return DLIST_RETURN_OK;  
  122. }  
  123.   
  124. DListReturn dlist_print(DList* thiz, DListPrintFunction print)  
  125. {  
  126.     DListNode* iter = thiz->head;  
  127.   
  128.     while(iter != NULL)  
  129.     {  
  130.         print(iter->data);  
  131.         iteriter = iter->next;  
  132.     }  
  133.     printf("\n");  
  134.     return DLIST_RETURN_OK;  
  135. }  
  136.   
  137. DListReturn print_int(void* data)  
  138. {  
  139.     DStu* ss=(DStu*)data;  
  140.     printf("%d\t ", ss->score);  
  141.   
  142.     return DLIST_RETURN_OK;  
  143. }  
  144.   
  145. DListReturn dlist_node_destroy(DListNode* node)  
  146. {  
  147.     if(node != NULL)  
  148.     {  
  149.         node->next = NULL;  
  150.         node->prev = NULL;  
  151.         free(node);  
  152.     }  
  153.   
  154.     return DLIST_RETURN_OK;  
  155. }  
  156.   
  157. DListReturn dlist_destroy(DList* thiz)  
  158. {  
  159.     DListNode* iter = thiz->head;  
  160.     DListNode* next = NULL;  
  161.   
  162.     while(iter != NULL)  
  163.     {  
  164.         next = iter->next;  
  165.         dlist_node_destroy(iter);  
  166.         iter = next;  
  167.     }  
  168.   
  169.     thiz->head = NULL;  
  170.     free(thiz);  
  171.   
  172.     return DLIST_RETURN_OK;  
  173. }  
  174.   
  175. int main(int argc, char* argv[])  
  176. {  
  177.     int i = 0;  
  178.     int n = 10;  
  179.       
  180.     DList* dlist = dlist_head_create();  
  181.     DStu* stu[7];  
  182.   
  183.     for(i = 0; i < 7; i++)  
  184.     {  
  185.         stu[i] =(DStu*) malloc(sizeof(DStu));  
  186.         stu[i]->score = i;  
  187.         dlist_append(dlist, (void*)stu[i]);       
  188.     }  
  189.   
  190.     dlist_print(dlist, print_int);  
  191.   
  192.     for(i = 0; i < 7; i++)  
  193.     {  
  194.         free(stu[i]);  
  195.     }  
  196.     return 0;  
  197. }

52/5<12345>
2023测试行业从业人员调查问卷已开启,千元大奖正在等你~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号