Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1743361
  • 博文数量: 1493
  • 博客积分: 38
  • 博客等级: 民兵
  • 技术积分: 5834
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-19 17:28
文章分类

全部博文(1493)

文章存档

2016年(11)

2015年(38)

2014年(137)

2013年(253)

2012年(1054)

2011年(1)

分类:

2012-10-10 15:24:45

原文地址:二级链表 作者:HuangLei_LEGO

    快乐学习,快乐生活!

点击(此处)折叠或打开

  1. /**
  2.  * 通用平台逻辑模块组
  3.  * Copyright (c) 2012 xxxx
  4.  *
  5.  * @file linkers.c
  6.  * @brief 二级链表
  7.  * @author
  8.  * @date 2012/10/9
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>

  15. /**
  16.  * @brief 二级链表
  17.  */
  18. typedef struct _Menu Menu;
  19. typedef struct _ChildMenu ChildMenu;

  20. /// < 第二级链表
  21. struct _ChildMenu
  22. {
  23.     char * m_name;
  24.     ChildMenu * cNext;
  25. };

  26. /// < 第一级链表
  27. struct _Menu
  28. {
  29.     char * m_name;
  30.     Menu * pMenu;

  31.     int count;
  32.     ChildMenu * pChildMenu;
  33. };

  34. /// < 初始化链表
  35. Menu * initMenu()
  36. {
  37.     Menu * pHead = NULL;
  38.     Menu * pNext = NULL;
  39.     ChildMenu * pcHead = NULL;

  40.     int i , j;

  41.     for (i = 0; i < 2; i)
  42.     {
  43.         Menu * pMenu = (Menu *)malloc(sizeof(Menu));
  44.         if (!pMenu)
  45.             return NULL;
  46.         memset(pMenu, 0, sizeof(Menu));

  47.         pMenu->m_name = (char *)malloc(3);
  48.         if (!pMenu->m_name)
  49.             return NULL;
  50.         memset(pMenu->m_name, 0, 3);
  51.         strcpy(pMenu->m_name, "a");

  52.         pMenu->count = 2;

  53.         if (0 == i)
  54.         {
  55.             pHead = pNext = pMenu;
  56.             pMenu->pMenu = NULL;
  57.         }
  58.         else
  59.         {
  60.             pNext->pMenu = pMenu;
  61.             pMenu->pMenu = NULL;
  62.             pNext = pMenu;
  63.         }

  64.         for (j = 0; j < pMenu->count; j)
  65.         {
  66.             ChildMenu * pChildMenu = (ChildMenu *)malloc(sizeof(ChildMenu));
  67.             if (!pChildMenu)
  68.                 return NULL;
  69.             pChildMenu->m_name = (char *)malloc(3);
  70.             if (!pChildMenu->m_name)
  71.                 return NULL;
  72.             memset(pChildMenu->m_name, 0, 3);
  73.             strcpy(pChildMenu->m_name, "b");

  74.             if (0 == j)
  75.             {
  76.                 pNext->pChildMenu = pChildMenu;
  77.                 pcHead = pChildMenu;
  78.                 pChildMenu->cNext = NULL;
  79.             }
  80.             else
  81.             {
  82.                 pcHead->cNext = pChildMenu;
  83.                 pChildMenu->cNext = NULL;
  84.                 pcHead = pChildMenu;
  85.             }
  86.         }
  87.     }

  88.     return pHead;
  89. }

  90. /// < 二级链表的遍历
  91. void traverse_linker(const Menu * head)
  92. {
  93.     const Menu * p = head;
  94.     ChildMenu * q;
  95.     int i;

  96.     if (!head)
  97.         return ;

  98.     while (p)
  99.     {
  100.         printf("-%s\n", p->m_name);
  101.         q = p->pChildMenu;
  102.         for (i = 0; i < p->count; i) /// < 有个数就是好!
  103.         {
  104.             printf(" --%s", q->m_name);
  105.             q = q->cNext;
  106.         }
  107.         putchar('\n');

  108.         p = p->pMenu;
  109.     }
  110. }

  111. /// < 二级链表的释放 - 从头开始
  112. void free_linker(Menu ** head)
  113. {
  114.     Menu * firstgo = NULL; /// < 负责一级链表
  115.     ChildMenu * childgo = NULL; /// < 负责二级链表
  116.     Menu * firstNext = NULL; /// < 指向一级链表的后一个
  117.     ChildMenu * childNext = NULL; /// < 指向二级链表后一个
  118.     if (!(*head))
  119.         return;
  120.     firstgo = *head;
  121.     while (firstgo)
  122.     {
  123.         firstNext = firstgo->pMenu;
  124.         childgo = firstgo->pChildMenu;
  125.         while (childgo)
  126.         {
  127.             /// < 释放第二级链表
  128.             childNext = childgo->cNext;
  129.             
  130.             free(childgo->m_name);
  131.             free(childgo);
  132.             /// < 下一个
  133.             childgo = childNext;
  134.         }
  135.         
  136.         /// < 释放第一级链表
  137.         free(firstgo->m_name);
  138.         free(firstgo);
  139.         /// < 下一个
  140.         firstgo = firstNext;
  141.     }
  142.     *head = NULL;
  143. }

  144. /**
  145.  * @brief 鉴于所使用的环境,carbide.c ;所以用gcc调试,用symbian os application进行内存泄漏检查!
  146.  * 突然发现symbian模拟器运行程序挺爽的,关闭后检查你的内存泄漏。挺好,应该还有很多工具可以检查,目前
  147.  * 这个不错!不过调试的话,看内存,看变量就可以了,不需要去打印哈!你懂的..
  148.  */
  149. int main()
  150. {
  151.     Menu * pMenu = initMenu();

  152.     /* printf("%s ", pMenu->m_name);
  153.        printf("%d\n", pMenu->count);
  154.        printf(" -->%s -->", pMenu->pChildMenu->m_name);
  155.        printf("%s\n", pMenu->pChildMenu->cNext->m_name);

  156.        printf("%s ", pMenu->pMenu->m_name);
  157.        printf("%d\n", pMenu->pMenu->count);
  158.        printf(" -->%s -->", pMenu->pMenu->pChildMenu->m_name);
  159.        printf("%s\n", pMenu->pMenu->pChildMenu->cNext->m_name);
  160.        */
  161.     traverse_linker(pMenu);
  162.     free_linker(&pMenu);
  163.     /// < 证明下
  164.     traverse_linker(pMenu);
  165.     return 0;
  166. }

点击(此处)折叠或打开

  1. /**
  2.  * 通用平台逻辑模块组
  3.  * Copyright (c) 2012 xxxx
  4.  *
  5.  * @file linkers2.c
  6.  * @brief 二级链表2
  7.  * @author
  8.  * @date 2012/10/9
  9.  *
  10.  */

  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>

  14. /**
  15.  * @brief 二级链表2
  16.  */
  17. typedef struct _Menu Menu;
  18. struct _Menu
  19. {
  20.     int id;
  21.     char * name;

  22.     Menu * brother; /// < 兄弟节点 - 作为一级链表
  23.     Menu * child; /// < 儿子节点 - 作为二级或者多级链表(针对节点结构都相同)
  24. };

  25. /**
  26.  * @brief 初始化
  27.  * 类似:
  28.  * -文件 --打开
  29.  * --保存
  30.  * --退出
  31.  *
  32.  * -1 --11
  33.  * --11
  34.  * --11
  35.  * -1 --11
  36.  * --11
  37.  * --11
  38.  */
  39. Menu * initial_link()
  40. {
  41.     Menu * head;
  42.     Menu * next;

  43.     Menu * cnext;

  44.     int i, j;
  45.     for (i = 0; i < 3; i) /// < 三兄弟
  46.     {
  47.         Menu * pTemp = (Menu *)malloc(sizeof(Menu));
  48.         if (!pTemp)
  49.             return NULL;
  50.         memset(pTemp, 0, sizeof(Menu));

  51.         pTemp->name = (char *)malloc(2);
  52.         if (!pTemp->name)
  53.             return NULL;
  54.         strcpy(pTemp->name, "1");
  55.         pTemp->id = 1;

  56.         if (0 == i)
  57.         {
  58.             head = next = pTemp;
  59.             pTemp->brother = NULL;
  60.             pTemp->child = NULL;
  61.         }
  62.         else
  63.         {
  64.             next->brother = pTemp;
  65.             pTemp->brother = NULL;
  66.             pTemp->child = NULL;
  67.             next = pTemp;
  68.         }

  69.         for (j = 0; j < 3; j) /// < 一个儿子,两个孙子
  70.         {
  71.             Menu * pTempc = (Menu *)malloc(sizeof(Menu));
  72.             if (!pTempc)
  73.                 return NULL;
  74.             memset(pTempc, 0, sizeof(Menu));

  75.             pTempc->name = (char *)malloc(3);
  76.             if (!pTempc->name)
  77.                 return NULL;
  78.             strcpy(pTempc->name, "11");
  79.             pTempc->id = 11;

  80.             if (0 == j)
  81.             {
  82.                 next->child = pTempc;
  83.                 cnext = pTempc;
  84.                 pTempc->brother = NULL;
  85.                 pTempc->child = NULL;
  86.             }
  87.             else
  88.             {
  89.                 cnext->child = pTempc;
  90.                 pTempc->brother = NULL;
  91.                 pTempc->child = NULL;
  92.                 cnext = pTempc;
  93.             }
  94.         }
  95.     }

  96.     return head;
  97. }

  98. /**
  99.  * @brief 遍历
  100.  */
  101. void traverse_linker(const Menu * head)
  102. {
  103.     const Menu * p = head;
  104.     const Menu * q;
  105.     if (!head)
  106.         return ;

  107.     while (p)
  108.     {
  109.         printf("-%d %s\n", p->id, p->name);
  110.         q = p->child;
  111.         while (q)
  112.         {
  113.             printf(" --%d %s\n", q->id, q->name);
  114.             q = q->child;
  115.         }
  116.         p = p->brother;
  117.     }
  118. }

  119. /*
  120.  * @brief 二级链表的释放 - 从头开始 和linker一样的方式。不过仔细一看这种方式有问题?儿子还有儿子没考虑!不过从经验来看,我们开发手机软件
  121.  * 所需要的菜单不会非常多,因此我们不必去绞尽脑汁像一个通用遍历的方法,没有必要!你认为了...
  122.  */
  123. void free_linker(Menu ** head)
  124. {
  125.     Menu * firstgo = NULL; /// < 负责一级链表
  126.     Menu * childgo = NULL; /// < 负责二级链表
  127.     Menu * firstNext = NULL; /// < 指向一级链表的后一个
  128.     Menu * childNext = NULL; /// < 指向二级链表后一个
  129.     if (!(*head))
  130.         return;
  131.     firstgo = *head;
  132.     while (firstgo)
  133.     {
  134.         firstNext = firstgo->brother;
  135.         childgo = firstgo->child;
  136.         while (childgo)
  137.         {
  138.             /// < 释放第二级链表
  139.             childNext = childgo->child;

  140.             free(childgo->name);
  141.             free(childgo);
  142.             /// < 下一个
  143.             childgo = childNext;
  144.         }

  145.         /// < 释放第一级链表
  146.         free(firstgo->name);
  147.         free(firstgo);
  148.         /// < 下一个
  149.         firstgo = firstNext;
  150.     }
  151.     *head = NULL;
  152. }


  153. int main(int argc, char **argv)
  154. {
  155.     Menu * head = initial_link();
  156.     traverse_linker(head);
  157.     free_linker(&head);

  158.     return 0;
  159. }
接着哦!

点击(此处)折叠或打开

  1. /*
  2.  ============================================================================
  3.  Name : linkerList3.c
  4.  Author : hl
  5.  Version :
  6.  Copyright : Copyright (c) 2012 Tiros
  7.  Description : Linker3 in C, Ansi-style
  8.  ============================================================================
  9.  */

  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>

  13. /**
  14.  * @brief 可扩展性的二级链表 (参考Company)
  15.  */
  16. typedef struct _linkerList linkerList;

  17. /**
  18.  * @brief “真实”数据
  19.  */
  20. typedef struct _Data
  21. {
  22.     int id;
  23.     char * name;
  24. }Data;

  25. /// < 链表结点 - 描述结点的子结点个数和数据信息
  26. typedef struct _linkerNodeData
  27. {
  28.     Data * pData; /// < 数据
  29.     int childNodesCount; /// < 子链表的个数
  30.     linkerList * plinkerList;
  31. }linkerNodeData;

  32. /// < 二级链表 - 之所以这样封装的原因:如果取消该包装,那么我们要实现二级链表就只能像之前,在linkerNodeData中定义一个brother指针来指向下一个条目,画画图就知道了;我们再linkerNodeData中"回调"linkerList就相当于包含了一个数据类型和指向下一个结点的指针的集合!
  33. struct _linkerList
  34. {
  35.    linkerNodeData * pNodeData;
  36.    linkerList * pNext;
  37. };

  38. static Data * createData(int id, char * name);
  39. static linkerList * cratelinkerList(int id, char * name, int count);
  40. static linkerNodeData * createlinkerNodeData(int id, char * name, int count);

  41. /**
  42.  * @brief "定值"初始化 问题很严重,代码冗余,逻辑混乱
  43.  */
  44. /*linkerList * initLinker()
  45. {
  46.    linkerList * pHead;
  47.    linkerList * pNext;
  48.    int i = 0;
  49.    int j = 0;

  50.    for ( ; i < 3; ++i) /// < 三个一级菜单条目
  51.    {
  52.        linkerList * pTmp = (linkerList *)malloc(sizeof(linkerList));
  53.        if (!pTmp)
  54.            return NULL;
  55.        pTmp->pNodeData = (linkerNodeData *)malloc(sizeof(linkerNodeData));
  56.        if (!pTmp->pNodeData)
  57.        {
  58.          free(pTmp);
  59.          return NULL;
  60.        }
  61.        pTmp->pNodeData->pData = (Data *)malloc(sizeof(Data));
  62.        if (!pTmp->pNodeData->pData)
  63.        {
  64.          free(pTmp);
  65.          free(pTmp->pNodeData);
  66.          return NULL;
  67.        }
  68.        pTmp->pNodeData->pData->id = i;
  69.        pTmp->pNodeData->pData->name = (char *)malloc(10);
  70.        if (!pTmp->pNodeData->pData->name)
  71.        {
  72.          free(pTmp);
  73.             free(pTmp->pNodeData);
  74.             free(pTmp->pNodeData->pData);
  75.             return NULL;
  76.        }
  77.        memset( pTmp->pNodeData->pData->name, 0, 10);
  78.        strcpy(pTmp->pNodeData->pData->name, "文件");

  79.        if (0 == i)
  80.        {
  81.          pHead = pNext = pTmp;    ///-------
  82.          pTmp->pNext = NULL;
  83.        }
  84.        else
  85.        {
  86.          pNext->pNext = pTmp;
  87.          pTmp->pNext = NULL;
  88.          pNext = pTmp;

  89.        }

  90.        pTmp->pNodeData->childNodesCount = 1;    /// < 一个二级菜单条目

  91.        for ( j = 0; j < pTmp->pNodeData->childNodesCount; ++j)
  92.        {
  93.             linkerList * ppTmp = (linkerList *) malloc(sizeof(linkerList));
  94.             if (!ppTmp)
  95.                 return NULL;
  96.             ppTmp->pNodeData = (linkerNodeData *) malloc(sizeof(linkerNodeData));
  97.             if (!ppTmp->pNodeData)
  98.             {
  99.                 free(ppTmp);
  100.                 return NULL;
  101.             }
  102.             ppTmp->pNodeData->pData = (Data *) malloc(sizeof(Data));
  103.             if (!ppTmp->pNodeData->pData)
  104.             {
  105.                 free(ppTmp);
  106.                 free(ppTmp->pNodeData);
  107.                 return NULL;
  108.             }
  109.             ppTmp->pNodeData->pData->id = j;
  110.             ppTmp->pNodeData->pData->name = (char *) malloc(10);
  111.             if (!ppTmp->pNodeData->pData->name)
  112.             {
  113.                 free(ppTmp);
  114.                 free(ppTmp->pNodeData);
  115.                 free(ppTmp->pNodeData->pData);
  116.                 return NULL;
  117.             }
  118.             memset(ppTmp->pNodeData->pData->name, 0, 10);
  119.             strcpy(ppTmp->pNodeData->pData->name, "打开");

  120.             ppTmp->pNodeData->childNodesCount = 0;
  121.             ppTmp->pNodeData->plinkerList = NULL;    /// < 无三级了

  122.             pNext->pNext = ppTmp;
  123.             ppTmp->pNext = NULL;
  124.         }
  125.    }
  126.    return pHead;
  127. }*/

  128. /**
  129.  * @brief 释放
  130.  */
  131. void freeListNode(linkerList * head)
  132. {
  133.     if (!head)
  134.         return ;
  135. }

  136. /**
  137.  * @brief 数据创建
  138.  */
  139. Data * createData(int id, char * name)
  140. {
  141.     Data * pData = (Data *)malloc(sizeof(Data));
  142.     if (!pData)
  143.         return NULL;
  144.     /// < 项id
  145.     pData->id = id;
  146.     /// < 项名称
  147.     pData->name = (char *)malloc(strlen(name) + 1);
  148.     if (!pData->name)
  149.     {
  150.         free(pData);
  151.         return NULL;
  152.     }
  153.     memset(pData->name, 0, strlen(name) + 1);
  154.     strcpy(pData->name, name);

  155.     return pData;
  156. }

  157. /**
  158.  * @brief 链表结点创建
  159.  */
  160. linkerNodeData * createlinkerNodeData(int id, char * name, int count)
  161. {
  162.     linkerNodeData * plinkerNodeData = (linkerNodeData *)malloc(sizeof(linkerNodeData));
  163.     int i = 0;
  164.     if (!plinkerNodeData)
  165.         return NULL;
  166.     memset(plinkerNodeData, 0, sizeof(linkerNodeData));
  167.     plinkerNodeData->pData = createData(id, name);
  168.     plinkerNodeData->childNodesCount = count;

  169.     linkerList * next;
  170.     for (i = 0; i < count; ++i)
  171.     {
  172.         linkerList * plinkerList = cratelinkerList(i, name, --count);    ///特别注意
  173.         if (!plinkerList)
  174.             return NULL;
  175.         if (!plinkerNodeData->plinkerList)
  176.         {
  177.             plinkerNodeData->plinkerList = plinkerList;
  178.             next = plinkerList;
  179.             plinkerList->pNext = NULL;
  180.         }
  181.         else
  182.         {
  183.             next->pNext = plinkerList;
  184.             next = plinkerList;
  185.             plinkerList->pNext = NULL;
  186.         }
  187.     }
  188.     return plinkerNodeData;
  189. }

  190. /**
  191.  * @brief 链表创建
  192.  */
  193. linkerList * cratelinkerList(int id, char * name, int count)
  194. {
  195.     linkerList * plinkerList = NULL;    /// < 链表头指针

  196.     plinkerList = (linkerList *) malloc(sizeof(linkerList));
  197.     if (!plinkerList)
  198.         return NULL;
  199.     memset(plinkerList, 0, sizeof(linkerList));
  200.     plinkerList->pNodeData = createlinkerNodeData(id, name, count);

  201.     if (!plinkerList->pNodeData)
  202.         return NULL;

  203.     return plinkerList;
  204. }


  205. /**
  206.  * @brief "定值"初始化
  207.  */
  208. linkerList * initLinker()
  209. {
  210.     linkerList * head = NULL;
  211.     linkerList * next = NULL;
  212.     int i = 0;

  213.     head = (linkerList *) malloc(sizeof(linkerList));
  214.     if (!head)
  215.         return NULL;
  216.     memset(head, 0, sizeof(linkerList));

  217.     for ( ; i < 3; ++i)    /// < 3个一级链表
  218.     {
  219.         linkerList * pTmp = cratelinkerList(i, "文件", 2); /// < 每个一级含2个二级的
  220.         if (0 == i)
  221.         {
  222.             next = head = pTmp;
  223.             pTmp->pNext = NULL;
  224.         }
  225.         else
  226.         {
  227.             next->pNext = pTmp;
  228.             next = pTmp;
  229.             pTmp->pNext = NULL;
  230.         }
  231.     }
  232.     return head;
  233. }

  234. /**
  235.  * @brief 遍历二级链表
  236.  */
  237. void traverseLinker(linkerList * head)
  238. {
  239.     //TODO
  240. }

  241. /**
  242.  * @brief 释放
  243.  */
  244. void releaseLinker(linkerList * head)
  245. {
  246.     //TODO
  247. }

  248. /**
  249.  * @brief 最大的收获就是函数相互调用!感觉挺麻烦的,调试也麻烦,稍微写错了,就死循环!或者失败!
  250.  */
  251. int main(void)
  252. {
  253.     linkerList * plinkerList = initLinker();
  254.     traverseLinker(plinkerList);

  255.     return EXIT_SUCCESS;
  256. }
自拍..
.
阅读(239) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~