二叉树的创建

对于创建一棵二叉树,首先想到的方法是使用递归思想进行。这里,采用先序递归创建二叉树。

首先介绍下自己写的二叉树的定义:

1 typedef int TElementType;
2
3 typedef struct BiTNode
4 {
5     TElementType data;
6     BiTNode* leftChild,*rightChild;
7 } BiTNode,*BiTree;

1.先序递归创建二叉树

先附上自己最开始写的代码:

 1 //太丑了!!
 2 void CreateTreeDLR(BiTree _biTree)
 3 {
 4     TElementType data;
 5     cin>>data;
 6     if(data==0)
 7     {
 8        _biTree=NULL;
 9         return;
10     }
11     _biTree->data=data;
12     _biTree->leftChild=new BiTNode();
13     FillTreeDLR(_biTree->leftChild);
14     _biTree->rightChild=new BiTNode();
15     FillTreeDLR(_biTree->rightChild);
16 }

因为需要传入一个BiTree类型,所以需要在外部初始化一个BiTree类型。这时候问题就来了,但出现终止条件0时,虽然能正常结束递归,但_biTree=NULL语句对外层的BiTree对象根本不起作用。所以会导致出现一个不含值的BiTree类型。就会出现如下情况:

input:1 2 4 0 0 5 0 0 3 6 0 0 7 0 0

output:1 2 4 0 0 5 0 0 3 6 0 0 7 0 0 (使用先序遍历)

输出结果出现0,完全不是我们想要的。

既然知道了问题所在,那么进行如下改进:

 1 //传址的方法,也解决了因为传值需要在外部初始化BiTNode的问题
 2 //怎么一开始就转不过来!!
 3 void FillTreeDLR(BiTree &_biTree)
 4 {
 5     TElementType data;
 6     cin>>data;
 7     if(data==0)
 8     {
 9        _biTree=NULL;
10     }
11     else
12     {
13     _biTree=new BiTNode();
14     _biTree->data=data;
15     FillTreeDLR(_biTree->leftChild);
16     FillTreeDLR(_biTree->rightChild);
17     }
18 }

当然,如果不想使用传入参数,可以采用返回值得形式。

 1 //这个代码貌似还是有点违反“不能返回局部初始化的指针”这一原则
 2 BiTNode* CreateTreeDLR()
 3 {
 4     TElementType data;
 5     cin>>data;
 6     if(data==0)
 7     {
 8         return NULL;
 9     }
10     BiTNode* root=new BiTNode();
11     root->data=data;
12     root->leftChild=CreateTreeDLR();
13     root->rightChild=CreateTreeDLR();
14     return root;
15 }

执行结果符合我们的需求:

input:1 2 4 0 0 5 0 0 3 6 0 0 7 0 0

output:1 2 4 5 3 6 7  (使用先序遍历)

2.非递归创建二叉树

非递归创建二叉树的思想跟层序遍历的思想类似,利用到队列,当弹出一个结点时,对当前结点进行赋值,如果值为空(这里值是0),则表明该结点无后续子结点;否则,将该结点的左右孩子入队列。依此过程,直到队列为空,结束。

但是在一开始创建二叉树的时候,还是因为对指针的掌握不够,还是犯了将指针进行传值操作,后面使用指针的指针来解决这问题的。这一点在以后的学习中再怎么强调也不为过啊,指针真的把我绕晕了。

首先,重新定义了下二叉树。

1 typedef struct BiTNode
2 {
3     TElementType data;
4     BiTNode* leftChild,*rightChild;
5 } BiTNode,*BiTree,**BiTreePtr;/*新添加指针的指针*/

下面是我实现的非递归创建二叉树的算法,说实话,对于下面指针的指针的用法,要如何改进优化,我晕乎着,反正是看不出来了。

 1 void CreateTreeNonRecur(BiTree& root)
 2 {
 3     queue<BiTreePtr> q;
 4     TElementType data;
 5     q.push(&root);
 6     while(q.size()!=0)
 7     {
 8         //弹出要配置的结点
 9         BiTreePtr r=q.front();
10         q.pop();
11         //输入数据
12         cin>>data;
13         if(data==0){
14             *r=NULL;
15             continue;
16         }
17         *r=new BiTNode();
18         (*r)->data=data;
19         //压入新的子结点
20         q.push(&((*r)->leftChild));
21         q.push(&((*r)->rightChild));
22     }
23 }

测试结果:

input:1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0

output:1 2 4 8 5 3 6 7 (使用先序遍历)

时间: 2024-10-31 17:35:56

二叉树的创建的相关文章

数据结构与算法 3:二叉树,遍历,创建,释放,拷贝,求高度,面试,线索树

[本文谢绝转载,原文来自http://990487026.blog.51cto.com] 树 数据结构与算法 3:二叉树,遍历,创建,释放,拷贝,求高度,面试,线索树 二叉树的创建,关系建立 二叉树的创建,关系建立2 三叉链表法 双亲链表: 二叉树的遍历 遍历的分析PPT 计算二叉树中叶子节点的数目:使用全局变量计数器 计算二叉树中叶子节点的数目:不使用全局变量计数器 无论是先序遍历,中序遍历,后序遍历,求叶子的数字都不变;因为本质都是一样的,任何一个节点都会遍历3趟 求二叉树的高度 二叉树的拷

二叉树基本操作--创建,三种遍历,叶子节点

虽然二叉树的操作很常见,但是认真写写熟悉很重要,特别是typedef, CreateBiTree(BiTNode** T)指针的操作等等,还有就是创建方法,去实际输入值就知道其中的妙处,为-1时为空节点. #include <iostream> using namespace std; //节点的定义 typedef struct BTNode { int data; BTNode* rChild; BTNode* lChild; }BiTNode, *BiTree; //二叉树的创建,先序创

创建二叉树、创建链表等

方法一: 1 #include <iostream>//创建二叉树,要用二级指针 2 3 using namespace std; 4 5 typedef struct TreeNode 6 { 7 char data; 8 struct TreeNode *left; 9 struct TreeNode *right; 10 }BiTree; 11 12 void creatBitree(BiTree **T) 13 { 14 char ch; 15 cin >> ch; 16

算法实验-二叉树的创建和前序-中序-后序-层次 遍历

对于二叉树的创建我是利用先序遍历的序列进行创建 能够对于树节点的内容我定义为char型变量 '0'为空,即此处的节点不存在 头文件 Tree.h //链式二叉树的头文件 #pragma once #include<iostream> #include<queue> using namespace std; class BinaryTreeNode { public: char data; BinaryTreeNode *leftChild,*rightChild; BinaryTr

二叉树的创建和四种遍历(前序、先序、后序、层次、结点的层数、深度、叶子数等)—java描述

二叉树的创建和四种遍历(前序.先序.后序.层次.结点的层数.深度.叶子数等)—java描述 package javab; //树的结点类 public class TreeNode { String data; TreeNode leftChild,rightChild,next; public TreeNode(String data){ this.data=data; } public TreeNode(String data,TreeNode left,TreeNode right){ l

数据结构与算法第10周作业——二叉树的创建和遍历算法

一.二叉树的创建算法(递归方式) 二.二叉树的先序.中序和后序遍历算法 #include<stdio.h>#include<stdlib.h>typedef struct TNode{ struct TNode *lchild; int data; struct TNode *rchild;}TNode,*BTree;void createBiTree(BTree &T){ char x; scanf("%d",&x); if(x!=0) { T

【数据结构之二叉树】二叉树的创建、遍历等操作

二叉树的基本操作: 1.创建二叉树 2.销毁二叉树 3.遍历二叉树:1)前序遍历 2)中序遍历 3)后序遍历 4)层次遍历 4.搜索二叉树 5.删除子叶 6.插入子叶 7.获取左/右子叶的值 8.获取树深度 9.获取叶子结点数 1.创建二叉树 这里创建的是链式存储结构的二叉树,包含数据域,左右两结点的指针域:在读取创建树时,以#代替空格,输入格式的规范为:以前序遍历的顺序输入,如果该结点的左子叶为空,则输入#,以此类推: e.g: -  +         \ a    *    e    f 

二叉树的创建、遍历

二叉树的创建.这里采用最简单的情况,创建完全二叉树,用数组来保存: 1 struct TreeNode 2 { 3 int val; 4 TreeNode *left, *right; 5 TreeNode(int x): val(x), left(NULL), right(NULL) {}; 6 }; 7 8 void CreatTree(TreeNode *root, int idx, int A[], int n) //root结点已分配,idx为根结点的编号 9 { 10 if(2 *

二叉树 二叉树的性质 存储结构 遍历二叉树 C实现二叉树的创建和遍历 线索二叉树

定义 二叉树(binary tree)是n(n>=0)个结点的有限集合,该集合为空集合称为空二叉树,或者有一个根结点和两棵互不相交的,分别称为树根结点的左孩子树和右孩子树组成. 二叉树的特点 每个结点最多有两棵子树,所以二叉树总没有度大于2的结点 左子树和右子树是有顺序的,次数不能任意颠倒 即使树中某结点只有一棵子树,也要区分是左子树还是右子树 特殊的二叉树 1. 斜树 所有的结点都只有左子树的二叉树称为左斜树; 所有的结点都只有右子树的二叉树称为右斜树; 这两者统称为斜树 2. 满二叉树 在一

二叉树的创建,插入,查找和比较

二叉树的结构 function TreeNode(){ this.val = val; this.left = null; this.right = null; } 二叉树的创建 function createBTree(aVal,fPredicate,pos){ var node = {}; pos = pos || 0; if(fPredicate(aVal,pos) || !aVal[pos]){ return null; } else{ node.val = aVal[pos]; nod