当前位置:   article > 正文

关于二叉树的建立(C语言)(链式)_struct bitnode *lchild

struct bitnode *lchild

      首先,我们得知道二叉树是什么!!这东西网上一大把。

      还有,二叉树的遍历顺序,前序(根左右),中序(左根右),后序(左右根)一般用递归来实现,而层序用队列(先父亲进,然后父亲出,接着儿子进,以此类推)。

而今天我要讲的是二叉树的建立需要主要谈指针和结构体,还有typedef吧!

     第一是结构体和typedef吧;

  1. typedef char ElemType;
  2. typedef struct BitNode
  3. {
  4. ElemType date;
  5. struct BitNode *lChild,*rChild;
  6. }Bitnode;
  1. typedef char ElemType;
  2. typedef struct BitNode
  3. {
  4. ElemType date;
  5. struct BitNode *lChild,*rChild;
  6. }BTree;

这两种方法都行!

里面的struct BitNode *lChild,*rChild;之所以不报错是因为外面的typedef struct BitNode,加了一个typedef之后这个结构就相当于有了自己的独有身份,自己也可以使用自己(用于构建自己的左右子树),也可以向外延伸比如Bitnode;,BTree;也可以使用指针类型的如*tree;啊等等,在其他函数中可以使用你向外延伸的身份了,如果非要用你原来的身份的话,那就得按照C语言结构体的声明方法使用了(跟建二叉树的左右子树一样)。

    第二是创建二叉树的主要函数:

  1. void builtTree(BTree **root){
  2. char ch;
  3. scanf("%c",&ch);
  4. if(ch=='#'){
  5. *root=NULL;
  6. return ;
  7. }
  8. else
  9. {
  10. *root=(BTree *)malloc(sizeof(BTree));
  11. (*root)->date=ch;
  12. }
  13. builtTree(&((*root)->lChild));
  14. builtTree(&((*root)->rChild));
  15. }

这里呢,我使用的是我朋友教我的二级指针。为什么要这样使用?因为你要想啊!你的左右子树都是指针,你干嘛不是指针。而一级指针是可以在其他封装函数修改指针指向的变量值的,而二级指针则是修改指针指向的指针(地址)。这也是在之后递归创建左右子树埋下扎实的种子(模板)。

  1. if(ch=='#'){
  2. *root=NULL;
  3. return ;
  4. }

这一步,我时常会忘掉写return;没有return的话,它会默认继续创建子树,造成无限递归,也就造成二叉树的建立失败。还有这里是 *root=NULL;,而为什么不是**root,就跟你用一级指针的时候一样,当你使用的有*的时候你可以修改里面的值,而你不使用*的时候,它总会联系到指针这方面去,你的目的是修改指针指向的指针,而为什么不用root,同样你的目的是修改指针指向的指针。

还有啊,我们应该都知道&这是取地址符,这个*是取值符;而root是指向*root的指针(已经定义的情况下),*root是指向**root的指针。

看似有点绕,其实还真的有点绕,谁叫指针学起来就是有点绕。你也可以直接写一个返回指针

  1. else
  2. {
  3. *root=(BTree *)malloc(sizeof(BTree));
  4. (*root)->date=ch;
  5. }

使用#include <stdlib.h>的头文件,开拓空间给*root,(sizeof(BTree))这个是说给你多少空间,(BTree *)这是将你创建出来的东西强制转化类型,加个*表示为指针类型。

  1. builtTree(&((*root)->lChild));
  2. builtTree(&((*root)->rChild));

这是根据先序(左根右)的方式进行创建二叉树的。还有要使用&取孩纸指针的地址(原理和根结点一样)。

第三是遍历二叉树的函数(前序遍历)

  1. void PreOrderTraverse(BTree *T, int level)
  2. {
  3. if (T)
  4. {
  5. vist(T->date, level);
  6. PreOrderTraverse(T->lChild, level + 1);
  7. PreOrderTraverse(T->rChild, level + 1);
  8. }
  9. }

上面已经把指针指向设置好了,现在只需要使用它就完事了,我选择使用一级指针而不用二级指针,是不想杀鸡用牛刀而已。你也可以用。

  1. void PreOrderTraverse(BTree **T, int level)
  2. {
  3. if (*T)
  4. {
  5. vist((*T)->date, level);
  6. PreOrderTraverse(&((*T)->lChild), level + 1);
  7. PreOrderTraverse(&((*T)->rChild), level + 1);
  8. }
  9. }

第三是打印函数

  1. void vist(char c, int level)
  2. {
  3.     printf("%c位于%d层\n", c, level);
  4. }

封装函数好处多多,不过参数传的要准确对应,不然会脑阔疼

最后全代码是

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char ElemType;
  4. typedef struct BitNode
  5. {
  6. ElemType date;
  7. struct BitNode *lChild,*rChild;
  8. }BTree;
  9. void builtTree(BTree **root){
  10. char ch;
  11. scanf("%c",&ch);
  12. if(ch=='#'){
  13. *root=NULL;
  14. return ;
  15. }
  16. else
  17. {
  18. *root=(BTree *)malloc(sizeof(BTree));
  19. (*root)->date=ch;
  20. }
  21. builtTree(&((*root)->lChild));
  22. builtTree(&((*root)->rChild));
  23. }
  24. void vist(char c, int level)
  25. {
  26. printf("%c位于%d层\n", c, level);
  27. }
  28. void PreOrderTraverse(BTree *T, int level)//一级指针
  29. {
  30. if (T)
  31. {
  32. vist(T->date, level);
  33. PreOrderTraverse(T->lChild, level + 1);
  34. PreOrderTraverse(T->rChild, level + 1);
  35. }
  36. }
  37. //void PreOrderTraverse(BTree **T, int level)
  38. //{
  39. // if (*T)
  40. // {
  41. // vist((*T)->date, level);
  42. // PreOrderTraverse(&((*T)->lChild), level + 1);
  43. //
  44. // PreOrderTraverse(&((*T)->rChild), level + 1);
  45. // }
  46. //}
  47. int main()
  48. {
  49. printf("请输入二叉树的各个结点以字符‘# ’为空子树,当你输入一棵完整的二叉树后它自然会打印:\n");
  50. int level = 1;
  51. BTree **tree;
  52. builtTree(&tree);
  53. // PreOrderTraverse(&tree, level);//二级指针
  54. PreOrderTraverse(tree, level);
  55. return 0;
  56. }

你还可以用

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct BitNode
  4. {
  5. char data;//结点数据
  6. struct BitNode *lChild, *rChild;//指向左右子树的指针
  7. } BitNode, *Bittree;//对应变量的名称
  8. void CreateBitree(Bittree *T)//默认按照先序遍历的方式存储树
  9. {
  10. char c;
  11. scanf("%c", &c);
  12. if ('#' == c)//当c为#时,为空
  13. {
  14. *T = NULL;
  15. }
  16. else
  17. {
  18. *T = (BitNode *)malloc(sizeof(BitNode));
  19. (*T)->data = c;
  20. CreateBitree(&(*T)->lChild);
  21. CreateBitree(&(*T)->rChild);
  22. }
  23. }
  24. void vist(char c, int level)
  25. {
  26. printf("%c位于%d层\n", c, level);
  27. }
  28. void PreOrderTraverse(Bittree T, int level)
  29. {
  30. if (T)
  31. {
  32. vist(T->data, level);
  33. PreOrderTraverse(T->lChild, level + 1);
  34. PreOrderTraverse(T->rChild, level + 1);
  35. }
  36. }
  37. int main()
  38. {
  39. int level = 1;
  40. Bittree T = NULL;
  41. CreateBitree(&T);
  42. PreOrderTraverse(T, level);
  43. return 0 ;
  44. }

两者都行,或者其他逻辑和我的差不多。要么就用数组的方法.

最后·,希望这东西对您有用。

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

闽ICP备14008679号