C语言二叉树的创建、(先中后序)遍历以及存在的问题
#include<stdlib.h>
#include<stdio.h> #define True 1
#define False 0 typedef char TElemType;
typedef struct TNode {
TElemType data;
struct TNode *lchild, *rchild;
}TNode,*BinTree; int CreateBinTree(BinTree T)
{
TElemType ch;
scanf("%c",&ch);
if (ch == '#')
T = NULL;
else
{
T = (TNode *)malloc(sizeof(TNode));
T->data = ch;
CreateBinTree(T->lchild);//创建左子树
CreateBinTree(T->rchild);//创建右子树
}
return ;
} void PreOrderTraverse(BinTree T) //先序遍历
{
if (T!=NULL)
{
// Visit(T->data);
printf("%c", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
} void InOrderTraverse(BinTree T) //中序遍历
{
if (T != NULL)
{
InOrderTraverse(T->lchild);
// Visit(T->data);
printf("%c", T->data);
InOrderTraverse(T->rchild);
}
} void PostOrderTraverse(BinTree T) //后序遍历
{
if (T != NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c", T->data);
}
} int main()
{
BinTree a;
CreateBinTree(a);
PreOrderTraverse(a);
return ;
}
满怀憧憬写完了代码,让我绝望的是,一运行就出现了问题:能够输入树的信息,但是无法输出,因此,我认为是二叉树的遍历函数出了问题,但是又无法单单从代码看出
于是,我就写了如下代码,自行构建了一个二叉树:
BinTree a=NULL;
BinTree b = NULL;
BinTree c = NULL;
a = (BinTree)malloc(sizeof(TNode));
b = (BinTree)malloc(sizeof(TNode));
c = (BinTree)malloc(sizeof(TNode));
a->rchild = b;
b->lchild = c;
a->lchild = NULL;
b->rchild = NULL;
c->lchild = NULL;
c->rchild = NULL;
a->data = 'A';
b->data = 'B';
c->data = 'C'; PreOrderTraverse(a);
printf("\n");
InOrderTraverse(a);
printf("\n");
PostOrderTraverse(a);
结果却成功地输出了自行构造的二叉树。由此可见我的遍历函数并没有问题,因此必定是二叉树的create函数出了问题,但是为何我却能够输入呢?
我在网上查了查相关的代码,发现一个采用引用值传递的算法,将create函数修改如下:
int CreateBinTree(BinTree &T) //引用值传递
{
TElemType ch;
scanf_s("%c",&ch,sizeof(ch));
if (ch == '#')
T = NULL;
else
{
T = (TNode *)malloc(sizeof(TNode));
T->data = ch;
CreateBinTree(T->lchild);//构造左子树
CreateBinTree(T->rchild);//构造右子树
}
return ;
}
尝试着运行,成功了!
???这时我感到很奇怪。
为啥之前的不行呢?
这时,又看到使用BinTree作返回值的算法,修改后如下:
BinTree creatBTree() //以BinTree为返回值
{
TElemType ch;
BinTree T;
scanf_s("%c", &ch, sizeof(ch));
if (ch == '#')
T = NULL;
else
{
T = (TNode *)malloc(sizeof(TNode));
T->data = ch;
T->lchild=creatBTree();//构造左子树
T->rchild=creatBTree();//构造右子树
}
return T;
}
毫无疑问,同样能成功实现需求。
那么问题来了?为什么之前的不行呢?
因为我之前用的int CreateBinTree(BinTree T);是单纯的值传递,就像swap(a,b)无法交换两值那样,虽然的确通过动态内存分配和链表构造了一个二叉树,但是在主函数中定义的a的值并没有任何改变,因此在遍历a时会毫无反应。
而引用作函数参数传递,能够直接对a的值进行改变,以a为根节点构建二叉树。
以BinTree为返回值就更不用说了,直接将新构建的二叉树赋值给a。
为了尝试地址为参数传递是否可行,写了如下函数
int CreateRoot(BinTree *T),细节如下:
int CreateBinTree(BinTree *T)
{
TElemType ch;
scanf("%c",&ch);
*T=(BinTree)malloc(sizeof(TNode));
(*T)->data=ch;
(*T)->lchild=NULL;
(*T)->rchild=NULL;//设置左右孩子为NULL,以防陷入无限循环
}
能够成功插入根节点!
看到这里,便可以轻松完成递归构造函数:
int CreateBinTree(BinTree *T)
{
TElemType ch;
scanf("%c",&ch);
if (ch == '#')
*T = NULL; //若写成T=NULL ,可能会陷入无限循环
else
{
*T = (BinTree)malloc(sizeof(TNode));
(*T)->data = ch;
CreateBinTree(&(*T)->lchild);//left child
CreateBinTree(&(*T)->rchild);//right child
}
return ;
}
//在本函数中最需要注意的就是,所有地方都必须以(*T)的形式出现
写完这个随笔,对二叉树的理解增进了不少,今天的学习给我带来了不小的回报,继续努力~
C语言二叉树的创建、(先中后序)遍历以及存在的问题的更多相关文章
- [C++] 非递归实现前中后序遍历二叉树
目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...
- C语言实现链式二叉树静态创建,(先序遍历),(中序遍历),(后续遍历)
#include <stdio.h>#include <stdlib.h> struct BTNode{ char data ; struct BTNode * pLchild ...
- 数据结构-C语言递归实现树的前中后序遍历
#include <stdio.h> #include <stdlib.h> typedef struct tree { int number ; struct tree *l ...
- Binary Tree Traversal 二叉树的前中后序遍历
[抄题]:二叉树前序遍历 [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: 节点非空时往左移,否则新取一个点 再往右移. [输入量] ...
- POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)
链接:poj.org/problem?id=2255 本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html 题意: 分别给你一个二叉树的前序遍历序列和中序 ...
- C++二叉树前中后序遍历(递归&非递归)统一代码格式
统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理. 三种递归格式: 前序遍历: void PreOrder(TreeNode* root, vector<int>&pa ...
- C++实现对树的创建和前中后序遍历
#include<iostream>#include<stdio.h> using namespace std; class BitNode{ public: char dat ...
- 剑指offer面试题:输入某二叉树的前序遍历和中序遍历,输出后序遍历
二叉树的先序,中序,后序如何遍历,不在此多说了.直接看题目描述吧(题目摘自九度oj剑指offer面试题6): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...
- 【遍历二叉树】03二叉树的后序遍历【Binary Tree Postorder Traversal】
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的后序遍历的 ...
随机推荐
- [LeetCode] LRU Cache [Forward]
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- Size Classes with Xcode 6:为所有的尺寸准备一个Storyboard
我最喜欢的Xcode6的特性是新的size classes 概念,有了它,我们解决了“我如何能够快速的为那么多不同尺寸屏幕以及方向的设备写app”.他们也让在一个storyboard中创建一个通用的a ...
- Python基础 — OS
OS模块 -- 简介 OS模块是Python标准库中的一个用于访问操作系统功能的模块,OS模块提供了一种可移植的方法使用操作系统的功能.使用OS模块中提供的接口,可以实现跨平台访问.但是在OS模块 ...
- 慕课网6-4 编程练习:jQuery选择器中的过滤器
6-4 编程练习 结合所学的jQuery过滤器知识,实现如下图所示的隔行换色效果 任务 使用jQuery的.css()方法设置样式,语法css('属性 '属性值') 使用:odd和:even过滤器实现 ...
- 13、git
安装Git 网上有很多Git安装教程,如果需要图形界面,windows下建议使用TortoiseGit,linux建议使用Git GUI或者GITK.(windows下载exe安装包,linux可以使 ...
- Font Awesome矢量图标
下载 font-awesome 文件夹到您的项目中. 在HTML的 <head> 中引用font-awesome.min.css. 可以将Font Awesome图标使用在几乎任何地方,只 ...
- 数据结构之动态顺序表(C实现)
线性表有2种,分为顺序表和链表. 顺序表: 采用顺序存储方式,在一组地址连续的存储空间上存储数据元素的线性表(长度固定) 链表: 有3种,单链表.双向链表.循环链表(长度不固定) seqList.h ...
- service: no such service mysqld 与MySQL的开启,关闭和重启
1.问题原因与解决办法 因为修改了MySQL临时文件的目录后,使用service mysqld restart重启MySQL出现如下错误: service: no such service mysql ...
- 每天学点Linux命令: 管道| 与 xargs的区别
先看一个例子: find ./ -print | xargs grep a 输出: grep: ./: 是一个目录 ./less:abc ./afile:abcde ./afile:AaAbBcB . ...
- PS技巧汇总
一.gif图流程 1:素材图片a 图片b 2:窗口--->时间轴/动画 3:复制所选帧--->设置帧延迟 4:文件--->存储为WEB格式--->gif格式 二.批处理--- ...