赞
踩
首先,我们得知道二叉树是什么!!这东西网上一大把。
还有,二叉树的遍历顺序,前序(根左右),中序(左根右),后序(左右根)一般用递归来实现,而层序用队列(先父亲进,然后父亲出,接着儿子进,以此类推)。
而今天我要讲的是二叉树的建立需要主要谈指针和结构体,还有typedef吧!
第一是结构体和typedef吧;
- typedef char ElemType;
- typedef struct BitNode
- {
- ElemType date;
- struct BitNode *lChild,*rChild;
-
- }Bitnode;
- typedef char ElemType;
- typedef struct BitNode
- {
- ElemType date;
- struct BitNode *lChild,*rChild;
-
- }BTree;
这两种方法都行!
里面的struct BitNode *lChild,*rChild;之所以不报错是因为外面的typedef struct BitNode,加了一个typedef之后这个结构就相当于有了自己的独有身份,自己也可以使用自己(用于构建自己的左右子树),也可以向外延伸比如Bitnode;,BTree;也可以使用指针类型的如*tree;啊等等,在其他函数中可以使用你向外延伸的身份了,如果非要用你原来的身份的话,那就得按照C语言结构体的声明方法使用了(跟建二叉树的左右子树一样)。
第二是创建二叉树的主要函数:
- void builtTree(BTree **root){
- char ch;
-
- scanf("%c",&ch);
- if(ch=='#'){
- *root=NULL;
- return ;
- }
- else
- {
- *root=(BTree *)malloc(sizeof(BTree));
- (*root)->date=ch;
- }
- builtTree(&((*root)->lChild));
- builtTree(&((*root)->rChild));
- }

这里呢,我使用的是我朋友教我的二级指针。为什么要这样使用?因为你要想啊!你的左右子树都是指针,你干嘛不是指针。而一级指针是可以在其他封装函数修改指针指向的变量值的,而二级指针则是修改指针指向的指针(地址)。这也是在之后递归创建左右子树埋下扎实的种子(模板)。
- if(ch=='#'){
- *root=NULL;
- return ;
- }
这一步,我时常会忘掉写return;没有return的话,它会默认继续创建子树,造成无限递归,也就造成二叉树的建立失败。还有这里是 *root=NULL;,而为什么不是**root,就跟你用一级指针的时候一样,当你使用的有*的时候你可以修改里面的值,而你不使用*的时候,它总会联系到指针这方面去,你的目的是修改指针指向的指针,而为什么不用root,同样你的目的是修改指针指向的指针。
还有啊,我们应该都知道&这是取地址符,这个*是取值符;而root是指向*root的指针(已经定义的情况下),*root是指向**root的指针。
看似有点绕,其实还真的有点绕,谁叫指针学起来就是有点绕。你也可以直接写一个返回指针
- else
- {
- *root=(BTree *)malloc(sizeof(BTree));
- (*root)->date=ch;
- }
使用#include <stdlib.h>的头文件,开拓空间给*root,(sizeof(BTree))这个是说给你多少空间,(BTree *)这是将你创建出来的东西强制转化类型,加个*表示为指针类型。
- builtTree(&((*root)->lChild));
- builtTree(&((*root)->rChild));
这是根据先序(左根右)的方式进行创建二叉树的。还有要使用&取孩纸指针的地址(原理和根结点一样)。
第三是遍历二叉树的函数(前序遍历)
- void PreOrderTraverse(BTree *T, int level)
- {
- if (T)
- {
- vist(T->date, level);
- PreOrderTraverse(T->lChild, level + 1);
- PreOrderTraverse(T->rChild, level + 1);
- }
- }
上面已经把指针指向设置好了,现在只需要使用它就完事了,我选择使用一级指针而不用二级指针,是不想杀鸡用牛刀而已。你也可以用。
- void PreOrderTraverse(BTree **T, int level)
- {
- if (*T)
- {
- vist((*T)->date, level);
- PreOrderTraverse(&((*T)->lChild), level + 1);
-
- PreOrderTraverse(&((*T)->rChild), level + 1);
- }
- }
第三是打印函数
- void vist(char c, int level)
- {
- printf("%c位于%d层\n", c, level);
- }
封装函数好处多多,不过参数传的要准确对应,不然会脑阔疼
最后全代码是
- #include <stdio.h>
- #include <stdlib.h>
- typedef char ElemType;
- typedef struct BitNode
- {
- ElemType date;
- struct BitNode *lChild,*rChild;
-
- }BTree;
- void builtTree(BTree **root){
- char ch;
-
- scanf("%c",&ch);
- if(ch=='#'){
- *root=NULL;
- return ;
- }
- else
- {
- *root=(BTree *)malloc(sizeof(BTree));
- (*root)->date=ch;
- }
- builtTree(&((*root)->lChild));
- builtTree(&((*root)->rChild));
- }
- void vist(char c, int level)
- {
- printf("%c位于%d层\n", c, level);
- }
- void PreOrderTraverse(BTree *T, int level)//一级指针
- {
- if (T)
- {
- vist(T->date, level);
- PreOrderTraverse(T->lChild, level + 1);
- PreOrderTraverse(T->rChild, level + 1);
- }
- }
- //void PreOrderTraverse(BTree **T, int level)
- //{
- // if (*T)
- // {
- // vist((*T)->date, level);
- // PreOrderTraverse(&((*T)->lChild), level + 1);
- //
- // PreOrderTraverse(&((*T)->rChild), level + 1);
- // }
- //}
- int main()
- {
- printf("请输入二叉树的各个结点以字符‘# ’为空子树,当你输入一棵完整的二叉树后它自然会打印:\n");
- int level = 1;
- BTree **tree;
- builtTree(&tree);
- // PreOrderTraverse(&tree, level);//二级指针
- PreOrderTraverse(tree, level);
- return 0;
- }

你还可以用
- #include <stdio.h>
- #include <stdlib.h>
- typedef struct BitNode
- {
- char data;//结点数据
- struct BitNode *lChild, *rChild;//指向左右子树的指针
- } BitNode, *Bittree;//对应变量的名称
- void CreateBitree(Bittree *T)//默认按照先序遍历的方式存储树
- {
- char c;
- scanf("%c", &c);
- if ('#' == c)//当c为#时,为空
- {
- *T = NULL;
- }
- else
- {
- *T = (BitNode *)malloc(sizeof(BitNode));
- (*T)->data = c;
- CreateBitree(&(*T)->lChild);
- CreateBitree(&(*T)->rChild);
- }
- }
- void vist(char c, int level)
- {
- printf("%c位于%d层\n", c, level);
- }
- void PreOrderTraverse(Bittree T, int level)
- {
- if (T)
- {
- vist(T->data, level);
- PreOrderTraverse(T->lChild, level + 1);
- PreOrderTraverse(T->rChild, level + 1);
- }
- }
- int main()
- {
- int level = 1;
- Bittree T = NULL;
- CreateBitree(&T);
- PreOrderTraverse(T, level);
-
- return 0 ;
- }

两者都行,或者其他逻辑和我的差不多。要么就用数组的方法.
最后·,希望这东西对您有用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。