当前位置:   article > 正文

数据结构—树的实现(C语言)_树形结构c如何实现

树形结构c如何实现

1、树的概念
    树形结构是节点之间以及分支关系定义的层次结构。作为一种重要的非线性结构,树形结构中一个节点最多只有一个前驱节点,但是可以有多个后继节点。

2、树的存储结构
    在计算机中,树有多种的存储方式,下面介绍一种动态的“左子/右兄”二叉链表表示方法。
  1. #include "mytree.h"
  2. #include <vector>
  3. using namespace std;
  4. #define OK (0)
  5. #define ERROR (-1)
  6. #define MAX_NAME_LEN (50) //最大的名字长度
  7. /*树结构体中数据成员*/
  8. typedef struct _ElementType
  9. {
  10. int id;
  11. char name[MAX_NAME_LEN];
  12. }ElementType;
  13. /*树节点结构体*/
  14. typedef struct _TreeNode
  15. {
  16. int index;//结点的标识
  17. ElementType element; //数据域
  18. struct _TreeNode *FirstChild; //第一个孩子指针
  19. struct _TreeNode *NextSibing; //下一个兄弟 指针
  20. }TreeNode;
  21. /*树结构体*/
  22. typedef struct _CTree
  23. {
  24. int num; //节点个数
  25. vector<int> nodeIndexs;//存放所有的结点index
  26. int rootIndex;//根节点的index
  27. TreeNode *root; //根节点指针
  28. }CTree;
  29. /*全局数据保存树信息*/
  30. CTree g_tree;
  31. /*
  32. * 功能:检测结点的index是否正确
  33. * 入参:要检测的结点index
  34. * 返回值:合法index返回true,不合法的index返回false
  35. */
  36. static bool mytree_check_node_index(const int index)
  37. {
  38. vector<int>::iterator it;
  39. for(it = g_tree.nodeIndexs.begin(); it != g_tree.nodeIndexs.end(); ++it )
  40. {
  41. if(*it == index)
  42. {
  43. return true;
  44. }
  45. }
  46. return false;
  47. }
  48. /*
  49. * 功能:获取指定的结点指针
  50. * 入参:父节点,比较参数index,出参nodeinfo
  51. * 返回值:NA
  52. */
  53. void mytree_preorder_get_node(TreeNode *tree, int index, TreeNode *nodeinfo)
  54. {
  55. if (NULL != tree)
  56. {
  57. if (tree->index == index)
  58. {
  59. nodeinfo = tree;
  60. return;
  61. }
  62. mytree_preorder_get_node(tree->FirstChild, index, nodeinfo);
  63. mytree_preorder_get_node(tree->NextSibing, index, nodeinfo);
  64. }
  65. return ;
  66. }
  67. /*
  68. * 功能:通过结点的index获取结点的指针信息
  69. * 入参:查询结点的index
  70. * 返回值:成功返回指向结点的指针,不成功返回NULL
  71. */
  72. TreeNode *mytree_get_node_by_index(const int index)
  73. {
  74. TreeNode *tmpNode = NULL;
  75. TreeNode *root = NULL;
  76. if(true != mytree_check_node_index(index))
  77. {
  78. printf("invalied index\n");
  79. return NULL;
  80. }
  81. root = g_tree.root;
  82. //遍历当前的树,返回指定结点的指针
  83. mytree_preorder_get_node(root, index, tmpNode);
  84. return tmpNode;
  85. }
  86. /*
  87. * 功能:设置一个孩子到树中
  88. * 入参:parentIndex: 父节点的index
  89. element :孩子结点的信息
  90. * 返回值:插入成功返回0, 失败返回-1
  91. */
  92. int mytree_set_child(int parentIndex, int index, ElementType element)
  93. {
  94. TreeNode *parentNode = NULL;
  95. TreeNode *newNode = NULL;
  96. TreeNode *head = NULL;
  97. TreeNode *lastChild = NULL;
  98. //检测父节点是否有效
  99. if(true != mytree_check_node_index(parentIndex))
  100. {
  101. printf("invalied parent index\n");
  102. return ERROR;
  103. }
  104. parentNode = mytree_get_node_by_index(parentIndex);
  105. if (NULL == parentNode)
  106. {
  107. return ERROR;
  108. }
  109. //lastChild = mytree_get_last_child(parentNode);
  110. newNode = (TreeNode *)malloc(sizeof(TreeNode));
  111. if(NULL == newNode)
  112. {
  113. return ERROR;
  114. }
  115. memset(newNode, 0, sizeof(TreeNode));
  116. newNode->index = index;
  117. newNode->element.id = element.id;
  118. memcpy(newNode->element.name, element.name, MAX_NAME_LEN);
  119. g_tree.nodeIndexs.push_back(index);
  120. g_tree.num++;
  121. if (NULL == parentNode->FirstChild)
  122. {
  123. parentNode->FirstChild = newNode;
  124. return OK;
  125. }
  126. if(NULL == parentNode->NextSibing)
  127. {
  128. parentNode->NextSibing = newNode;
  129. return OK;
  130. }
  131. head = parentNode->NextSibing;
  132. while(head)
  133. {
  134. lastChild = head;
  135. head = head->NextSibing;
  136. }
  137. lastChild->NextSibing = newNode;
  138. return OK;
  139. }
  140. /*
  141. * 功能:设置一个树的根节点
  142. * 入参: element :根结点的信息
  143. * 返回值:插入成功返回0, 失败返回-1
  144. */
  145. int mytree_set_root( ElementType element)
  146. {
  147. //检测父节点是否有效
  148. TreeNode *newNode = NULL;
  149. newNode = (TreeNode *)malloc(sizeof(TreeNode));
  150. if (NULL == newNode)
  151. {
  152. return ERROR;
  153. }
  154. memset(newNode, 0, sizeof(TreeNode));
  155. newNode->index = 0;//根节点index
  156. newNode->FirstChild = NULL;
  157. newNode->NextSibing = NULL;
  158. newNode->element.id = element.id;
  159. memcpy(newNode->element.name, element.name, MAX_NAME_LEN);
  160. g_tree.nodeIndexs.push_back(0);
  161. g_tree.num++;
  162. g_tree.root = newNode;
  163. return OK;
  164. }
  165. /*
  166. * 功能:初始化当前树
  167. * 入参:无
  168. * 返回值:无
  169. */
  170. void mytree_init()
  171. {
  172. g_tree.num = 0;
  173. g_tree.rootIndex = 0;
  174. g_tree.root = NULL;
  175. return;
  176. }
  177. /*
  178. * 功能:获取指定的结点指针
  179. * 入参:父节点,比较参数index,出参nodeinfo
  180. * 返回值:NA
  181. */
  182. void mytree_preorder_visit(TreeNode *tree)
  183. {
  184. if (NULL != tree)
  185. {
  186. printf("tree index :%d\n", tree->index);
  187. printf("tree element id :%d\n", tree->element.id);
  188. printf("tree element id :%s\n", tree->element.name);
  189. mytree_preorder_get_node(tree->FirstChild);
  190. mytree_preorder_get_node(tree->NextSibing);
  191. }
  192. return ;
  193. }
  194. /*
  195. * 功能:打印整个树的结点
  196. * 入参:父节点,比较参数index,出参nodeinfo
  197. * 返回值:NA
  198. */
  199. void mytree_dump()
  200. {
  201. // 各种遍历方式去访问树的各个结点
  202. mytree_preorder_visit(g_tree.root)
  203. return ;
  204. }
  205. /*
  206. * 功能:创建一棵树
  207. * 入参:无
  208. * 返回值:无
  209. */
  210. void mytree_create()
  211. {
  212. ElementType element;
  213. memset(&element, 0, sizeof(ElementType));
  214. //初始化一棵树
  215. mytree_init();
  216. //设置树的根节点
  217. element.id = 0;
  218. strcncpy(element.name, "root", sizeof(element.name)-1);
  219. mytree_set_root(element);
  220. //设置叶子结点
  221. memset(&element, 0, sizeof(ElementType));
  222. element.id = 1;
  223. strcncpy(element.name, "root-child-1", sizeof(element.name)-1);
  224. mytree_set_child(0, 1, element);
  225. memset(&element, 0, sizeof(ElementType));
  226. element.id = 2;
  227. strcncpy(element.name, "root-child-2", sizeof(element.name)-1);
  228. mytree_set_child(0, 2, element);
  229. memset(&element, 0, sizeof(ElementType));
  230. element.id = 3;
  231. strcncpy(element.name, "root-child-3", sizeof(element.name)-1);
  232. mytree_set_child(0, 3, element);
  233. memset(&element, 0, sizeof(ElementType));
  234. element.id = 4;
  235. strcncpy(element.name, "root-child-1-1", sizeof(element.name)-1);
  236. mytree_set_child(1, 4, element);
  237. memset(&element, 0, sizeof(ElementType));
  238. element.id = 5;
  239. strcncpy(element.name, "root-child-1-2", sizeof(element.name)-1);
  240. mytree_set_child(1, 5, element);
  241. return ;
  242. }
  243. /*
  244. * 功能:测试当前树结构
  245. * 入参:无
  246. * 返回值:无
  247. */
  248. void tree_test()
  249. {
  250. //创建一棵树
  251. mytree_create();
  252. //打印树的结点
  253. mytree_dump();
  254. return ;
  255. }



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/669842
推荐阅读
相关标签
  

闽ICP备14008679号