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】
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的后序遍历的 ...
随机推荐
- 关于Flask的默认session
Flask的默认session利用了Werkzeug的SecureCookie,把信息做序列化(pickle)后编码(base64),放到cookie里了. 过期时间是通过cookie的过期时间实现的 ...
- 高效开发之写demo
今天花了不少时间排查发现了几个明显的错误,但是相关开发人员就是没发现,自己改了一个流程影响到了其它的.最后解决问题的关键还是通过demo找到问题原因进而解决的. 这让我再次感觉到demo的重要性,以前 ...
- 第八周 Leetcode 44. Wildcard Matching 水题 (HARD)
Leetcode 44 实现一种类似正则表达式的字符串匹配功能. 复杂度要求不高, 调代码稍微费点劲.. 好像跟贪心也不太沾边, 总之 *把待匹配串分成若干个子串, 每一个子串尽量在模式串中靠前的部分 ...
- libnids 中哈希表的建立
//hash.c #include <sys/types.h>#include <sys/time.h>#include <stdio.h>#include < ...
- struct框架
配置文件struct-config.xml<?xml version="1.0"encoding="UTF-8"?><!DOCTYPE str ...
- Html5 编程题
1.请写出下面所示的控件的html 代码? <div> <div><a>姓名:</a><input type="text" ...
- MVC的学习-EF的认识
1.什么是EF EF又称持久层框架:平时C#定义的变量是保存到内存中的,一断电就没有了.而持久的意思是数据保存到硬盘盘里(数据库的sql查询是在硬盘里进行的,所以速度很慢).EF帮我们将一个对象保存到 ...
- MAMP中Python安装MySQLdb
Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口. MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Py ...
- U盘安装完美的WIN7操作系统教程
准备工作 首先备份或者在官网下载好您机器的驱动,否则完成后可能无法正常使用 ①一个有win7或者XP系统的电脑(制作启动盘用) ②一个4G以上的U盘 ③win7&win8系统包(请到官网下载或 ...
- oracle数据库跨库查询
create public database link mylink connect to orclname identified by orclpasswd using 'ORCL'; drop p ...