Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1064180
  • 博文数量: 573
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 66
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-28 16:21
文章分类

全部博文(573)

文章存档

2018年(3)

2016年(48)

2015年(522)

分类: C/C++

2015-12-02 15:10:41


点击(此处)折叠或打开

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>

  5. #define SZ_STRING 1024

  6. typedef char STRING[SZ_STRING];

  7. /************************************begin二叉树定义区****************************/
  8. /*二叉树的二叉线索存储表示*/
  9. /*可以得到全线索链表 : 全线索链表建成之后,就相当于双向循环链表一样使用,非常方便
  10. 但是它占用的空间大!*/
  11. typedef struct binaryallthrnode
  12. {
  13.     STRING name; /*结点名称*/
  14.     STRING value;     /*结点值*/
  15.     struct binaryallthrnode * prior; /*前驱指针*/
  16.     struct binaryallthrnode * next; /*后继指针*/
  17.     struct binaryallthrnode * leftchild;     /*左孩子指针*/
  18.     struct binaryallthrnode * rightchild;     /*右孩子指针*/
  19. }BINARYALLTHRNODE;

  20. typedef BINARYALLTHRNODE * BinaryAllThrNodePtr;

  21. int GetLeftRightchildLenByPreAndMid(char * cur_pre, char * cur_mid, int * leftlen, int * rightlen);
  22. int CreateBinaryAllThrTreeByPreAndMid(BinaryAllThrNodePtr * root, char * cur_pre, char * cur_mid);

  23. void PreAllThreading(BinaryAllThrNodePtr root, BinaryAllThrNodePtr * prenode);
  24. void MidAllThreading(BinaryAllThrNodePtr root, BinaryAllThrNodePtr * prenode);
  25. void PosAllThreading(BinaryAllThrNodePtr root, BinaryAllThrNodePtr * prenode);
  26. int CreateBinaryTreeAllThreading(BinaryAllThrNodePtr * threadhead, BinaryAllThrNodePtr root, int type);

  27. void PrintBinaryTreeNodeByPre(BinaryAllThrNodePtr root);
  28. void PrintBinaryTreeNodeByMid(BinaryAllThrNodePtr root);
  29. void PrintBinaryTreeNodeByPos(BinaryAllThrNodePtr root);
  30. void PrintBinaryAllThrTreeNodeByPre(BinaryAllThrNodePtr allthreadhead);
  31. void PrintBinaryAllThrTreeNodeByMid(BinaryAllThrNodePtr allthreadhead);
  32. void PrintBinaryAllThrTreeNodeByPos(BinaryAllThrNodePtr allthreadhead);

  33. void PreOrderTraverseAllThr(BinaryAllThrNodePtr allthreadhead, char * pre);
  34. void MidOrderTraverseAllThr(BinaryAllThrNodePtr allthreadhead, char * mid);
  35. void PosOrderTraverseAllThr(BinaryAllThrNodePtr allthreadhead, char * pos);

  36. /************************************end二叉树定义区****************************/

  37. STRING data[26];

  38. int main(int argc, char * * argv)
  39. {
  40.     printf("二叉树的二叉全线索存储结构!(可以得到全线索二叉树链表!)\n");
  41.     
  42.     int i;
  43.     for(i=0; i<26; i++) /*所有的数据域赋初值*/
  44.     {
  45.         /*特点:data数组的每个元素都是STRING*/
  46.         memset(data[i], 0, sizeof(STRING));
  47.     }
  48.     for(i=0; i<26; i++) /*给所有的数据域赋值*/
  49.     {
  50.         /*data数据域中的数据,即为26个字母的大写(65是A)*/
  51.         memset(data[i], 65+i, sizeof(char)*3);
  52.     }
  53.     
  54.     char pre[128]; /*前序序列*/
  55.     char mid[128]; /*中序序列*/
  56.     char pos[128]; /*后序序列*/
  57.     char lev[128]; /*层次序列*/
  58.     
  59.     printf("******************************************begin第1颗二叉树*******************************************\n");
  60.     
  61.     memset(pre, 0, sizeof(pre));
  62.     strcpy(pre, "ABDHIEJCFG");
  63.     printf("前序序列=[%s]\n", pre);
  64.     memset(mid, 0, sizeof(mid));
  65.     strcpy(mid, "HDIBJEAFCG");
  66.     printf("中序序列=[%s]\n", mid);
  67.     
  68.     printf("创建二叉线索存储结构的二叉树:\n");
  69.     BinaryAllThrNodePtr rootallthrnodeptr1 = NULL;
  70.     CreateBinaryAllThrTreeByPreAndMid(&rootallthrnodeptr1, pre, mid);
  71.     printf("按照中序遍历序列,打印出整颗二叉树:\n");
  72.     PrintBinaryTreeNodeByMid(rootallthrnodeptr1);
  73.     
  74.     BinaryAllThrNodePtr allthreadhead = NULL; /*全线索链表的头节点*/
  75.     printf("中序全线索化二叉树:\n");
  76.     CreateBinaryTreeAllThreading(&allthreadhead, rootallthrnodeptr1, 0); /*中序全线索化二叉树*/
  77.     printf("按照中序遍历序列,打印出整颗中序全线索化二叉树:\n");
  78.     PrintBinaryAllThrTreeNodeByMid(allthreadhead);
  79.     memset(mid, 0, sizeof(mid));
  80.     MidOrderTraverseAllThr(allthreadhead, mid);
  81.     printf("中序全线索化二叉树:中序遍历序列(非递归)........=[%s]\n", mid);
  82.     
  83.     printf("******************************************end第1颗二叉树*******************************************\n");
  84.     
  85.     printf("\n\n******************************************begin第2颗二叉树*******************************************\n");
  86.         
  87.     memset(pre, 0, sizeof(pre));
  88.     strcpy(pre, "ABDHIEJCFG");
  89.     printf("前序序列=[%s]\n", pre);
  90.     memset(mid, 0, sizeof(mid));
  91.     strcpy(mid, "HDIBJEAFCG");
  92.     printf("中序序列=[%s]\n", mid);
  93.     
  94.     printf("创建二叉线索存储结构的二叉树:\n");
  95.     BinaryAllThrNodePtr rootallthrnodeptr2 = NULL;
  96.     CreateBinaryAllThrTreeByPreAndMid(&rootallthrnodeptr2, pre, mid);
  97.     printf("按照先序遍历序列,打印出整颗二叉树:\n");
  98.     PrintBinaryTreeNodeByPre(rootallthrnodeptr2);
  99.     
  100.     printf("先序全线索化二叉树:\n");
  101.     CreateBinaryTreeAllThreading(&allthreadhead, rootallthrnodeptr2, -1); /*先序全线索化二叉树*/
  102.     printf("按照先序遍历序列,打印出整颗先序全线索化二叉树:\n");
  103.     PrintBinaryAllThrTreeNodeByPre(allthreadhead);
  104.     memset(pre, 0, sizeof(pre));
  105.     printf("====================================\n");
  106.     PreOrderTraverseAllThr(allthreadhead, pre);
  107.     printf("====================================\n");
  108.     printf("先序线索化二叉树:先序遍历序列(非递归)........=[%s]\n", pre);
  109.     
  110.     printf("******************************************end第2颗二叉树*******************************************\n");
  111.     
  112.     printf("\n\n******************************************begin第3颗二叉树*******************************************\n");
  113.     
  114.     memset(pre, 0, sizeof(pre));
  115.     strcpy(pre, "ABDHIEJCFG");
  116.     printf("前序序列=[%s]\n", pre);
  117.     memset(mid, 0, sizeof(mid));
  118.     strcpy(mid, "HDIBJEAFCG");
  119.     printf("中序序列=[%s]\n", mid);
  120.     
  121.     printf("创建二叉线索存储结构的二叉树:\n");
  122.     BinaryAllThrNodePtr rootallthrnodeptr3 = NULL;
  123.     CreateBinaryAllThrTreeByPreAndMid(&rootallthrnodeptr3, pre, mid);
  124.     printf("按照后序遍历序列,打印出整颗二叉树:\n");
  125.     PrintBinaryTreeNodeByPos(rootallthrnodeptr3);
  126.     
  127.     printf("后序线索化二叉树:\n");
  128.     CreateBinaryTreeAllThreading(&allthreadhead, rootallthrnodeptr3, 1); /*后序线索化二叉树*/
  129.     printf("按照后序遍历序列,打印出整颗后序线索化二叉树:\n");
  130.     PrintBinaryAllThrTreeNodeByPos(allthreadhead);
  131.     memset(pos, 0, sizeof(pos));
  132.     printf("====================================\n");
  133.     PosOrderTraverseAllThr(allthreadhead, pos);
  134.     printf("====================================\n");
  135.     printf("后序线索化二叉树:后序遍历序列(非递归)........=[%s]\n", pos);
  136.     
  137.     printf("******************************************end第3颗二叉树*******************************************\n");
  138.     
  139.     return 0;
  140. }

  141. /*************************************************************************
  142.  *函数名:PosOrderTraverseAllThr()
  143.  *功能:遍历后序全线索化二叉树(非递归)
  144.  *输入参数:
  145.  * allthreadhead :线索二叉树的头结点
  146.  *输出参数:
  147.  * mid : 后序序列
  148.  *返回值:空
  149.  *特点:非递归遍历时,如果有线索链表是可以方便的实现遍历,可以不用栈了。
  150. **************************************************************************/
  151. void PosOrderTraverseAllThr(BinaryAllThrNodePtr allthreadhead, char * pos)
  152. {
  153.     BinaryAllThrNodePtr p = NULL;
  154.     p = allthreadhead->next; /*p指向后序序列的第一个结点*/
  155.     while(p != allthreadhead) /*p指向线索链表头allthreadhead时:表示遍历结束*/
  156.     {
  157.         /*printf("结点名=[%s], 结点值=[%s], LTag=[%d], RTag=[%d]\n", p->name, p->value, p->LTag, p->RTag);*/
  158.         strncat(pos, p->name, sizeof(char)*1); /*得到后序序列*/
  159.         p = p->next;
  160.     }
  161. }

  162. /*************************************************************************
  163.  *函数名:MidOrderTraverseAllThr()
  164.  *功能:遍历中序全线索化二叉树(非递归)
  165.  *输入参数:
  166.  * allthreadhead :线索二叉树的头结点
  167.  *输出参数:
  168.  * mid : 中序序列
  169.  *返回值:空
  170.  *特点:非递归遍历时,如果有线索链表是可以方便的实现遍历,可以不用栈了。
  171. **************************************************************************/
  172. void MidOrderTraverseAllThr(BinaryAllThrNodePtr allthreadhead, char * mid)
  173. {
  174.     BinaryAllThrNodePtr p = NULL;
  175.     p = allthreadhead->next; /*p指向中序序列的第一个结点*/
  176.     while(p != allthreadhead) /*p指向线索链表头allthreadhead时:表示遍历结束*/
  177.     {
  178.         /*printf("结点名=[%s], 结点值=[%s], LTag=[%d], RTag=[%d]\n", p->name, p->value, p->LTag, p->RTag);*/
  179.         strncat(mid, p->name, sizeof(char)*1); /*得到中序序列*/
  180.         p = p->next;
  181.     }
  182. }

  183. /*************************************************************************
  184.  *函数名:PreOrderTraverseAllThr()
  185.  *功能:遍历先序全线索化二叉树(非递归)
  186.  *输入参数:
  187.  * allthreadhead :线索二叉树的头结点
  188.  *输出参数:
  189.  * pre : 先序序列
  190.  *返回值:空
  191.  *特点:非递归遍历时,如果有线索链表是可以方便的实现遍历,可以不用栈了。
  192. **************************************************************************/
  193. void PreOrderTraverseAllThr(BinaryAllThrNodePtr allthreadhead, char * pre)
  194. {
  195.     BinaryAllThrNodePtr p = NULL;
  196.     p = allthreadhead->next; /*p指向先序序列的第一个结点*/
  197.     while(p != allthreadhead) /*p指向线索链表头allthreadhead时:表示遍历结束*/
  198.     {
  199.         /*printf("结点名=[%s], 结点值=[%s], LTag=[%d], RTag=[%d]\n", p->name, p->value, p->LTag, p->RTag);*/
  200.         strncat(pre, p->name, sizeof(char)*1); /*得到先序序列*/
  201.         p = p->next;
  202.     }
  203. }

  204. /*************************************************************
  205.  *函数名:PreAllThreading()
  206.  *功能:前序全线索化
  207.  *前序全线索化:是指用二叉链表结点数据结构建立二叉树的二叉链表,然后按照前序遍历的方法访问结点时建立线索。
  208.  *输入参数:
  209.  * root :二叉树的根结点
  210.  * prenode : 刚刚访问过的结点 :即为当前访问结点的前驱
  211.  *输出参数:
  212.  * prenode :
  213.  *返回值:空
  214.  *注意:第一次递归调用时,prenode指向线索链表的空头结点
  215.  *全线索化的实质:将二叉链表中的前驱和后继指针赋值,使之指向前驱结点或后继结点。
  216.  *线索化的过程:在遍历的过程中对前驱和后继指针赋值的过程
  217. **************************************************************/
  218. void PreAllThreading(BinaryAllThrNodePtr root, BinaryAllThrNodePtr * prenode)
  219. {
  220.     if(root == NULL)
  221.         return;
  222.     /*开始访问前序遍历的结点。*/
  223.     root->prior = (*prenode); /*加前驱线索*/
  224.     (*prenode)->next = root; /*加后继线索*/
  225.     *prenode = root; /*保证*prenode指向刚刚访问过的结点*/
  226.     
  227.     PreAllThreading(root->leftchild, prenode); /*左子树前序线索化*/
  228.     
  229.     PreAllThreading(root->rightchild, prenode); /*右子树前序线索化*/
  230. }

  231. /*************************************************************
  232.  *函数名:MidAllThreading()
  233.  *功能:中序全线索化
  234.  *中序全线索化:是指用二叉链表结点数据结构建立二叉树的二叉链表,然后按照中序遍历的方法访问结点时建立线索。
  235.  *输入参数:
  236.  * root :二叉树的根结点
  237.  * prenode : 刚刚访问过的结点 :即为当前访问结点的前驱
  238.  *输出参数:
  239.  * prenode :
  240.  *返回值:空
  241.  *注意:第一次递归调用时,prenode指向线索链表的空头结点
  242.  *全线索化的实质:将二叉链表中的前驱和后继指针赋值,使之指向前驱结点或后继结点。
  243.  *线索化的过程:在遍历的过程中对前驱和后继指针赋值的过程
  244. **************************************************************/
  245. void MidAllThreading(BinaryAllThrNodePtr root, BinaryAllThrNodePtr * prenode)
  246. {
  247.     if(root == NULL)
  248.         return;
  249.     MidAllThreading(root->leftchild, prenode); /*左子树中序线索化*/
  250.     /*开始访问中序遍历的结点。*/
  251.     root->prior = (*prenode); /*加前驱线索*/
  252.     (*prenode)->next = root; /*加后继线索*/
  253.     *prenode = root; /*保证*prenode指向刚刚访问过的结点*/
  254.     
  255.     MidAllThreading(root->rightchild, prenode); /*右子树中序线索化*/
  256. }

  257. /*************************************************************
  258.  *函数名:PosAllThreading()
  259.  *功能:后序全线索化
  260.  *后序全线索化:是指用二叉链表结点数据结构建立二叉树的二叉链表,然后按照后序遍历的方法访问结点时建立线索。
  261.  *输入参数:
  262.  * root :二叉树的根结点
  263.  * prenode : 刚刚访问过的结点 :即为当前访问结点的前驱
  264.  *输出参数:
  265.  * prenode :
  266.  *返回值:空
  267.  *注意:第一次递归调用时,prenode指向线索链表的空头结点
  268.  *全线索化的实质:将二叉链表中的前驱和后继指针赋值,使之指向前驱结点或后继结点。
  269.  *线索化的过程:在遍历的过程中对前驱和后继指针赋值的过程
  270. **************************************************************/
  271. void PosAllThreading(BinaryAllThrNodePtr root, BinaryAllThrNodePtr * prenode)
  272. {
  273.     if(root == NULL)
  274.         return;
  275.     PosAllThreading(root->leftchild, prenode); /*左子树后序线索化*/
  276.     
  277.     PosAllThreading(root->rightchild, prenode); /*右子树后序线索化*/
  278.     
  279.     /*开始访问后序遍历的结点。*/
  280.     root->prior = (*prenode); /*加前驱线索*/
  281.     (*prenode)->next = root; /*加后继线索*/
  282.     *prenode = root; /*保证*prenode指向刚刚访问过的结点*/
  283. }

  284. /*************************************************************
  285.  *函数名:CreateBinaryTreeAllThreading()
  286.  *功能:将二叉树全线索化,得到二叉树全线索链表
  287.  *输入参数:
  288.  * root :待线索化的二叉树根节点
  289.  * type : 全线索方式(-1: 先序遍历, 0:中序遍历, 1:后序遍历)
  290.  *输出参数:
  291.  * allthreadhead :全线索链表的头结点
  292.  *返回值:
  293.  * 0:成功 -1:失败
  294.  *全线索化的实质:将二叉链表中的前驱和后继指针赋值,使之指向前驱结点或后继结点。
  295.  *线索化的过程:在遍历的过程中对前驱和后继指针赋值的过程
  296. **************************************************************/
  297. int CreateBinaryTreeAllThreading(BinaryAllThrNodePtr * allthreadhead, BinaryAllThrNodePtr root, int type)
  298. {
  299.     BinaryAllThrNodePtr prenode = NULL; /*存放刚刚访问过的结点:即为当前访问结点的前驱*/
  300.     *allthreadhead = (BINARYALLTHRNODE *)malloc(sizeof(BINARYALLTHRNODE)); /*建立头结点*/
  301.     if(*allthreadhead == NULL)
  302.     {
  303.         printf("CreateBinaryTreeAllThreading malloc err!\n");
  304.         return -1;
  305.     }
  306.     (*allthreadhead)->leftchild = *allthreadhead; /*头结点左孩子指针暂时回指*/
  307.     (*allthreadhead)->rightchild = *allthreadhead; /*头结点右孩子指针暂时回指*/
  308.     (*allthreadhead)->prior = *allthreadhead; /*头结点的前驱指针暂时回指*/
  309.     (*allthreadhead)->next = *allthreadhead; /*头结点的后继指针暂时回指*/
  310.     if(root == NULL) /*若二叉树为空*/
  311.     {
  312.         (*allthreadhead)->leftchild = *allthreadhead; /*为空,则左孩子指针回指*/
  313.     }
  314.     else /*二叉树非空*/
  315.     {
  316.         (*allthreadhead)->leftchild = root; /*非空,则头结点的左孩子指向根结点*/
  317.         prenode = (*allthreadhead); /*刚刚访问过的结点记录下来,初始指向线索链表的空头结点*/
  318.         if(type == -1)
  319.         {
  320.             PreAllThreading(root, &prenode); /*前序线索化*/
  321.         }
  322.         else if(type == 0)
  323.         {
  324.             MidAllThreading(root, &prenode); /*中序线索化*/
  325.         }
  326.         else if(type == 1)
  327.         {
  328.             PosAllThreading(root, &prenode); /*后序线索化*/
  329.         }
  330.         else
  331.         {
  332.             printf("type 参数不对!\n");
  333.         }
  334.         /*prenode会指向遍历序列的最后一个结点 : 最后一个结点线索化*/
  335.         prenode->next = *allthreadhead; /*头结点前驱指针指向最后一个结点*/
  336.         (*allthreadhead)->prior = prenode; /*最后一个结点的后继指针指向头结点*/
  337.     }
  338. }

  339. /************************************
  340.  *函数名:GetLeftRightchildLenByPreAndMid()
  341.  *功能:根据二叉树的先序序列+中序序列,取得当前二叉树左右孩子的结点数
  342.  *输入参数:
  343.  * cur_pre: 当前二叉树的先序序列(其中:cur_pre中第一个元素,即是根元素结点)
  344.  * cur_mid: 当前二叉树的中序序列
  345.  *输出参数:
  346.  * leftlen: 当前二叉树左孩子的长度
  347.  * rightlen: 当前二叉树右孩子的长度
  348.  *返回值:
  349.  * 0:成功 -1:失败
  350.  *
  351.  *由二叉树的先序序列+中序序列,求当前二叉树的左右孩子的结点数方法:
  352.  * 先序序列的第一个元素就是当前二叉树的根结点。
  353.  *    在中序序列中对比根结点所在的位置,
  354.  *    则中序序列中根结点的左边就是根结点的左孩子,即可求出左孩子的结点数,
  355.  *    中序序列中根结点的右边就是根结点的右孩子,即可求出右孩子的结点数,
  356. *************************************/
  357. int GetLeftRightchildLenByPreAndMid(char * cur_pre, char * cur_mid, int * leftlen, int * rightlen)
  358. {
  359.     int left_len = 0;
  360.     if((cur_pre != NULL)&&(cur_mid != NULL)) /*序列非空,则树存在*/
  361.     {
  362.         /* *cur_pre:就是该二叉树的根结点 */
  363.         while(*(cur_mid+left_len) != *cur_pre) /*从中序序列的第一个元素开始与根元素比较*/
  364.         {
  365.             left_len++;
  366.         }
  367.         *leftlen = left_len;
  368.         /*当前二叉树右孩子的结点数=全树长-左孩子的结点数-根结点数*/
  369.         *rightlen = strlen(cur_pre) - left_len - 1;    
  370.     }
  371.     else
  372.     {
  373.         *leftlen = 0;
  374.         *rightlen = 0;    
  375.     }
  376.     return 0;
  377. }

  378. /**********************************************************
  379.  *函数名:CreateBinaryAllThrTreeByPreAndMid()
  380.  *功能:创建二叉树(由前序序列+中序序列,创建一颗二叉树)
  381.  *输入参数:
  382.  * cur_pre: 当前二叉树的先序序列
  383.  * cur_mid: 当前二叉树的中序序列
  384.  *输出参数:
  385.  * root: 二叉树的根结点
  386.  *返回值:
  387.  * 0-成功 -1-失败
  388.  *示例遍历序列编号:
  389.  *     先序序列=[A,B,D,H,I,E,J,C,F,G]
  390.  * 中序序列=[H,D,I,B,J,E,A,F,C,G]
  391.  * 后序序列=[H,I,D,J,E,B,F,G,C,A]
  392.  * 层次序列=[A,B,C,D,E,F,G,H,I,J]
  393.  *(由前序序列+中序序列,可唯一确定一颗二叉树)编程思路:
  394.  *        从当前二叉树先序序列cur_pre开始,第一个是根结点,再右边的leftlen个结点是左孩子,再右边rightlen个结点是右孩子,
  395.  *        则当前二叉树左孩子的先序序列从cur_pre+1地址开始,长:leftlen。当前二叉树右孩子的先序序列从cur_pre+1+leftlen地址开始,长:rightlen。
  396.  *     从当前二叉树中序序列根元素开始,左右分开,左边是当前二叉树左孩子,右边是当前二叉树右孩子。
  397.  *     则当前二叉树左孩子的中序序列继续从当前二叉树的中序序列的cur_mid地址开始,长:leftlen。当前二叉树右孩子的中序序列从cur_mid+leftlen+1地址开始,长:rightlen。
  398. ***********************************************************/
  399. int CreateBinaryAllThrTreeByPreAndMid(BinaryAllThrNodePtr * root, char * cur_pre, char * cur_mid)
  400. {
  401.     int i = 0;
  402.     int ret = -1;
  403.     int leftlen; /*当前二叉树左孩子的结点数*/
  404.     int rightlen; /*当前二叉树右孩子的结点数*/
  405.     char left_pre[128]; /*当前二叉树左孩子的先序序列*/
  406.     char left_mid[128]; /*当前二叉树左孩子的中序序列*/
  407.     char right_pre[128]; /*当前二叉树右孩子的先序序列*/
  408.     char right_mid[128]; /*当前二叉树右孩子的中序序列*/
  409.     
  410.     memset(left_pre, 0 ,sizeof(left_pre));
  411.     memset(left_mid, 0, sizeof(left_mid));
  412.     memset(right_pre, 0 ,sizeof(right_pre));
  413.     memset(right_mid, 0, sizeof(right_mid));
  414.     
  415.     if((cur_pre != NULL)&&(cur_mid != NULL)) /*当树的序列非空,则表明树是存在的*/
  416.     {
  417.         /*接下来创建一个结点的存储区域*/
  418.         *root = (BINARYALLTHRNODE *)malloc(sizeof(BINARYALLTHRNODE));
  419.         if(*root == NULL)
  420.         {
  421.             printf("CreateBinaryAllThrTreeByPreAndMid malloc err!\n");
  422.             return -1;
  423.         }
  424.         memset(*root, 0, sizeof(BINARYALLTHRNODE));
  425.         memset((*root)->name, 0, sizeof(STRING));
  426.         memset((*root)->value, 0, sizeof(STRING));
  427.         /*以当前二叉树先序序列cur_pre中的第一个元素(*cur_pre)作为域值来生成根结点*/
  428.         strncpy((*root)->name, cur_pre, sizeof(char)*1); /*填充根结点名*/
  429.         /*整颗二叉树是10个节点,data[i]中的数据是10个字符串,即为先序序列cur_pre中相同的数据*/
  430.         for(i=0; i<10; i++)
  431.         {
  432.             /*或者:if((*cur_pre) == data[i][0])*/
  433.             if(strncmp(cur_pre, data[i], sizeof(char)*1) == 0) /*定位结点数据域要填充的字符串*/
  434.             {
  435.                 strcpy((*root)->value, data[i]); /*填充根结点值*/
  436.                 break;
  437.             }
  438.         }
  439.         (*root)->prior = (*root)->next = NULL; /*前驱指针,后继指针*/
  440.         (*root)->leftchild = (*root)->rightchild = NULL; /*刚生成的节点左右孩子指针先赋NULL值*/
  441.         
  442.         /*获取当前二叉树左孩子的结点数leftlen, 右孩子的结点数rightlen*/
  443.         GetLeftRightchildLenByPreAndMid(cur_pre, cur_mid, &leftlen, &rightlen);
  444.         
  445.         memcpy(left_pre, cur_pre+1, leftlen); /*左孩子的先序序列*/
  446.         memcpy(left_mid, cur_mid, leftlen); /*左孩子的中序序列*/
  447.         /*printf("结点=[%c],左孩子:结点数=[%d],先序序列=[%s],中序序列=[%s]\n", *cur_pre, leftlen, left_pre,left_mid);*/
  448.         memcpy(right_pre, cur_pre+1+leftlen, rightlen); /*右孩子的先序序列*/
  449.         memcpy(right_mid, cur_mid+leftlen+1, rightlen); /*右孩子的中序序列*/
  450.         /*printf("结点=[%c],右孩子:结点数=[%d],先序序列=[%s],中序序列=[%s]\n", *cur_pre, rightlen, right_pre, right_mid);*/

  451.         if(leftlen > 0) /*当前二叉树左孩子存在,才需要创建这颗二叉树*/
  452.         {
  453.             ret = CreateBinaryAllThrTreeByPreAndMid(&((*root)->leftchild), left_pre, left_mid); /*创建当前二叉树的左孩子*/
  454.             if(ret < 0)
  455.                 return -1;
  456.         }

  457.         if(rightlen > 0) /*当前二叉树右孩子存在,才需要创建这颗二叉树*/
  458.         {
  459.             ret = CreateBinaryAllThrTreeByPreAndMid(&((*root)->rightchild), right_pre, right_mid); /*创建当前二叉树的右孩子*/
  460.             if(ret < 0)
  461.                 return -1;
  462.         }
  463.     }
  464.     else; /*树不存在,二叉树的根节点已经赋空,这里什么都不需要做*/
  465.     return 0;
  466. }

  467. /*功能:打印出整颗二叉树(按照先序遍历序列)*/
  468. void PrintBinaryTreeNodeByPre(BinaryAllThrNodePtr root)
  469. {
  470.     if(root == NULL)
  471.     {
  472.         return;
  473.     }
  474.     else
  475.     {
  476.         printf("结点名=[%s],结点值=[%s]\n", root->name, root->value);
  477.         PrintBinaryTreeNodeByPre(root->leftchild);
  478.         PrintBinaryTreeNodeByPre(root->rightchild);
  479.     }
  480. }

  481. /*功能:打印出整颗二叉树(按照中序遍历序列)*/
  482. void PrintBinaryTreeNodeByMid(BinaryAllThrNodePtr root)
  483. {
  484.     if(root == NULL)
  485.     {
  486.         return;
  487.     }
  488.     else
  489.     {
  490.         PrintBinaryTreeNodeByMid(root->leftchild);
  491.         printf("结点名=[%s],结点值=[%s]\n", root->name, root->value);
  492.         PrintBinaryTreeNodeByMid(root->rightchild);
  493.     }
  494. }

  495. /*功能:打印出整颗二叉树(按照后序遍历序列)*/
  496. void PrintBinaryTreeNodeByPos(BinaryAllThrNodePtr root)
  497. {
  498.     if(root == NULL)
  499.     {
  500.         return;
  501.     }
  502.     else
  503.     {
  504.         PrintBinaryTreeNodeByPos(root->leftchild);
  505.         PrintBinaryTreeNodeByPos(root->rightchild);
  506.         printf("结点名=[%s],结点值=[%s]\n", root->name, root->value);
  507.     }
  508. }

  509. /*功能:打印出整颗全线索二叉树(按照先序遍历序列)*/
  510. void PrintBinaryAllThrTreeNodeByPre(BinaryAllThrNodePtr allthreadhead)
  511. {
  512.     BinaryAllThrNodePtr p = NULL;
  513.     p = allthreadhead->next; /*p指向先序序列的第一个结点*/
  514.     while(p != allthreadhead) /*p指向线索链表头allthreadhead时:表示遍历结束*/
  515.     {
  516.         printf("结点名=[%s], 结点值=[%s]\n", p->name, p->value);
  517.         p = p->next;
  518.     }
  519. }

  520. /*功能:打印出整颗全线索二叉树(按照中序遍历序列)*/
  521. void PrintBinaryAllThrTreeNodeByMid(BinaryAllThrNodePtr allthreadhead)
  522. {
  523.     BinaryAllThrNodePtr p = NULL;
  524.     p = allthreadhead->next; /*p指向中序序列的第一个结点*/
  525.     while(p != allthreadhead) /*p指向线索链表头allthreadhead时:表示遍历结束*/
  526.     {
  527.         printf("结点名=[%s], 结点值=[%s]\n", p->name, p->value);
  528.         p = p->next;
  529.     }
  530. }

  531. /*功能:打印出整颗全线索二叉树(按照后序遍历序列)*/
  532. void PrintBinaryAllThrTreeNodeByPos(BinaryAllThrNodePtr allthreadhead)
  533. {
  534.     BinaryAllThrNodePtr p = NULL;
  535.     p = allthreadhead->next; /*p指向后序序列的第一个结点*/
  536.     while(p != allthreadhead) /*p指向线索链表头allthreadhead时:表示遍历结束*/
  537.     {
  538.         printf("结点名=[%s], 结点值=[%s]\n", p->name, p->value);
  539.         p = p->next;
  540.     }
  541. }

阅读(1147) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~