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】
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的后序遍历的 ...
随机推荐
- go语言---slice
go语言---slice https://blog.csdn.net/cyk2396/article/details/78893420 一.数组切片的使用: //1.基于数组创建数组切片 var ar ...
- emma中文显示乱码问题解决(ubutnu)
vim -/.emma/emmarc 找到 db_encoding=latin1 改为 db_encoding=utf8 然后重新运行emma,此时发现还是乱码,不要着急,在执行所有的sql语句 ...
- HTML文档中class的命名规则以及命名规范
1.采用英文字母.数字以及“-”和“_”命名. 2.以小写字母开头,不能以数字和“-”.“_”开头. 3.命名形式:单字,连字符,下划线和驼峰. 4.使用有意义命名. 其中(3).(4)条规定主要是便 ...
- 数组去重----es6&es5&数组对象去重
es6方法: 普通数组: 1.使用Array.from(new Set(arr)); /* * @param oldArr 带有重复项的旧数组 * @param newArr 去除重复项之后的新数组 ...
- 洛谷2019 3月月赛 T2
题干 洛谷同款 T2?(看似比T1简单些) 二维前缀和嘛?[多简单 我天天拿二维前缀和水DP] 这是前缀和的预处理 2333 处理出来所有的情况 某个地方要加上mod再%mod 如果没有这一步 那么 ...
- WKWebView 和 UIWebView 允许背景音乐自动播放(记录)
WKWebView WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; config.allowsInlin ...
- 如何快速部署Oracle Database
Oracle Database在Linux系统上的安装是每一个初学者都必须面临的问题,只有正确的配置好了环境,才能进行后续的深入学习.本文旨在说明如何快速的部署Oracle的单实例环境,对于初学者,还 ...
- 这样的设计是否有违背MVC设计原则??
MVC 皆知为 Model-View-Controller 请求模型-〉Client发现请求-〉Controller接收+处理-〉返回Model给前端-〉前端接收处理模型Result 但是最近发现一个 ...
- HTTP常见面试题
转自:http://www.cnblogs.com/Java3y/p/8444033.html Http与Https的区别: Http与Https的区别: HTTP 的URL 以http:// 开头, ...
- python数于字符串
python数于字符串 1.了解数的类型 2.什么事字符串 3.引号的使用与区别 4.转义符 5.自然字符串 6.字符串的重复 7.子字符串 #了解数的类型 1.python中数的类型主要有五种,分为 ...