二叉树的先中后序遍历

【0】README

0.1)本文旨在理清二叉树的先中后序遍历, 以及如何建立二叉树等相关内容;
0.2)本文涉及代码均为原创;
0.3)本文中遍历后的打印结果,朋友您可以直接写出二叉树的节点构造出来;
Attention):

  • A1)要建立二叉树或者普通树, 这就涉及到插入节点的问题; 进而涉及到找到插入到哪个父节点的哪个孩子问题(left or right);当然,我们可以抽取一个 find 方法出来找出父节点, find 方法的关键是 首先要对是否为空树进行测试;
  • A2) 而且,你要知道,在后面的二叉查找树的 插入方法insert 和 我们的 二叉树或者普通树的插入方法是不同的, 因为二叉查找树的定义是 :“该树中的每个节点 X, 它的左子树中所有关键字值 小于 X 的关键字值, 而它的右子树中所有关键字值大于 X 的关键字值”; 换句话说,在二叉查找树中,节点之间是有大小关联的, 而在二叉树和其它普通树中,节点间的数值大小是没有关系的,任意的 (特别要注意)

【1】二叉树相关概念

1.1)定义:二叉树是一颗树,其中每个节点都不能有多余两个儿子;
这里写图片描述
1.2)重要性质:平均二叉树的深度要比N小得多(N是该二叉树的节点个数);
这里写图片描述


【2】二叉树的表示方法说明:

2.1)树一般画成圆圈并用一些直线连接起来,因为二叉树实际上就是图,但涉及到树时, 我们也不明显地画出 NULL 指针,因为具有N个节点的每一个二叉树都将需要 N+1 个 NULL 指针;
2.2)为什么是N+1个NULL 指针? 因为N个节点==2N个指针==N-1条边;故余下N+1条边为 NULL , 即N+1个指针为NULL;(除根节点root外,每个节点都对应一条边)


【3】对二叉树的先序 + 中序 + 后序遍历

Attention)对于二叉树的遍历,我们的简单想法是, 遍历后的结果,我可以画出该二叉树节点的构造;
3.1)先序遍历步骤:如果二叉树为空树, 则什么都不做; 否则:

  • step1)访问根节点;
  • step2)先序遍历左子树;
  • step3)先序遍历右子树;
    这里写图片描述

3.1.1)download source code : https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter4/p70_preorder_binary_tree.c
这里写图片描述
3.1.2)source code at a glance :

#include <stdio.h>
#include <malloc.h>#define ElementType char
#define Error(str) printf("\n error: %s \n",str)   struct BinaryTree;
typedef struct BinaryTree *BinaryTree;BinaryTree createBinaryTree();
BinaryTree makeEmpty(BinaryTree t);
BinaryTree insert(ElementType e, BinaryTree t, int);// we adopt child-sibling notation
struct BinaryTree
{ElementType value;BinaryTree left;BinaryTree right;
};// create a BinaryTree with root node
BinaryTree createBinaryTree()
{   BinaryTree t;t = (BinaryTree)malloc(sizeof(struct BinaryTree));if(!t) {Error("out of space, from func createBinaryTree");        return NULL;}    t->left = NULL;t->right = NULL;    t->value = '/';return t;
}// make the BinaryTree empty 
BinaryTree makeEmpty(BinaryTree t)
{if(t){makeEmpty(t->left);makeEmpty(t->right);        free(t);}           return NULL;
}//insert a Tree node with value e into left child or right child of the parent
BinaryTree insert(ElementType e, BinaryTree parent, int isLeft)
{   BinaryTree node;if(!parent){Error("for parent BinaryTree node is empty , you cannot insert one into the parent node, from func insert");        return NULL;}node = (BinaryTree)malloc(sizeof(struct BinaryTree));if(!node) {Error("out of space, from func insert");        return NULL;}node->value = e;node->right = NULL;node->left = NULL;// building the node with value e overif(isLeft) { // the tree node inserting into left child of the parent if(parent->left) {Error("for parent has already had a left child , you cannot insert one into the left child, from func insert");        return NULL;    }parent->left = node;}else { // the tree node inserting into right child of the parent if(parent->right) {Error("for parent has already had a right child , you cannot insert one into the right child, from func insert");        return NULL;    }parent->right = node;}    return node;    
}// find the BinaryTree root node with value equaling to e
BinaryTree find(ElementType e, BinaryTree root)
{BinaryTree temp;if(root == NULL)return NULL;if(root->value == e)return root;temp = find(e, root->left); if(temp) return temp;elsereturn  find(e, root->right);               
}// analog print directories and files name in the BinaryTree, which involves postorder traversal. 
void printPreorder(int depth, BinaryTree root)
{           int i;if(root) {      for(i = 0; i < depth; i++)printf("    ");     printf("%c\n", root->value);printPreorder(depth + 1, root->left);                                           printPreorder(depth + 1, root->right); // Attention: there's difference between traversing binary tree and common tree                          }else {for(i = 0; i < depth; i++)printf("    ");     printf("NULL\n");}
}int main()
{BinaryTree BinaryTree;BinaryTree = createBinaryTree();printf("\n ====== test for postordering the BinaryTree presented by left_right_child structure  ====== \n");     printf("\n test for respectively inserting 'A' and 'B' into left and right child of the parent '/' , then 'C' and 'D' into the left and right child of the parent 'A' \n"); insert('A', find('/', BinaryTree), 1);  // 1 means left childinsert('B', find('/', BinaryTree), 0);  // 0 means right childinsert('C', find('A', BinaryTree), 1);insert('D', find('A', BinaryTree), 0);printPreorder(1, BinaryTree);printf("\n test for respectively inserting 'A' and 'B' into left and right child of the parent '/' \n");    insert('E', find('/', BinaryTree), 1);insert('F', find('/', BinaryTree), 0);printPreorder(1, BinaryTree); printf("\n test for inserting 'E' into the right child of the  parent 'B' , then repectively 'F' and 'G' into the left and right child of the parent 'H' \n");  insert('E', find('B', BinaryTree), 0);      insert('F', find('E', BinaryTree), 1);insert('G', find('E', BinaryTree), 0);printPreorder(1, BinaryTree); /**/return 0;
}

3.2)中序遍历步骤:如果二叉树为空树, 则什么都不做; 否则:

  • step1)中序遍历左子树;
  • step2)访问根节点;
  • step3)中序遍历右子树;
    这里写图片描述
    3.2.1)download source code : https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter4/p70_inorder_binary_tree.c
    这里写图片描述
    3.2.2)source code at a glance :Attention:要知道前序+中序+后序遍历的源代码的唯一不同是 打印函数的不同,这里,我们只给出中序的打印函数,其他的函数同前序是一样的,这里不再重复给出, 同时我们的后序遍历代码也只是给出了打印函数,其他函数同前序遍历一样,下文不再累述)
// analog print directories and files name in the BinaryTree, which involves postorder traversal. 
void printInorder(int depth, BinaryTree root)
{           int i;if(root) {              printInorder(depth + 1, root->left);                                            for(i = 0; i < depth; i++)printf("    ");     printf("%c\n", root->value);printInorder(depth + 1, root->right); // Attention: there's difference between traversing binary tree and common tree                           }else {for(i = 0; i < depth; i++)printf("    ");     printf("NULL\n");}
}

3.3)后序遍历步骤:如果二叉树为空树, 则什么都不做; 否则:

  • step1) 后序遍历左子树;
  • step2) 后序遍历右子树;
  • step3) 访问根节点;
    这里写图片描述
    3.3.1)download source code: https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter4/p70_postorder_binary_tree.c
    这里写图片描述
    3.3.2)source code at a glance:
// analog print directories and files name in the BinaryTree, which involves postorder traversal. 
void printPostorder(int depth, BinaryTree root)
{           int i;if(root) {                      printPostorder(depth + 1, root->left);                                          printPostorder(depth + 1, root->right); // Attention: there's difference between traversing binary tree and common treefor(i = 0; i < depth; i++)printf("    ");     printf("%c\n", root->value);                    }else {for(i = 0; i < depth; i++)printf("    ");     printf("NULL\n");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

表达式树

【0】README 0.1&#xff09;本文旨在总结出表达式树的构建步骤&#xff0c; 其中还涉及到中缀转后缀表达式&#xff0c;以及如何计算 表达式树中的值&#xff1b; 0.2&#xff09;本文源代码均为原创&#xff1b; 0.3&#xff09; 其实&#xff0c; 实现一个简单的计算器&a…

Date/Timestamp/String/LocalDate/LocalDateTime

文章目录String 转成 DateDate 转成 StringString 转成 Timestamp获取系统当前的毫秒数获取系统当前的日期时间毫秒数转成 Timestamp毫秒数转成 DateTimestamp 转成 StringDate 转成 TimestampTimestamp 转成 Datejava.util.Date 转成 java.sql.Date将带T的日期时间转成正常的日…

python可以用来写什么工具_python写工具

谷歌开源 Python Fire&#xff1a;可自动生成命令行接口今天我们很高兴地宣布 Python Fire 开源。Python Fire 可从任何 Python 代码生成命令行接口(command line interfaces (CLIs))&#xff0c;简单地调用任意 Python 程序中的 Fire 函数以将那个程序自动地转化为 CLI。该库可…

java原始类型和引用类型_Java中的8种原始类型

java原始类型和引用类型几年前&#xff0c;当我开始编辑Java Basics系列时&#xff0c;我认为将一些非常详细的信息拉到自己的帖子中是很有意义的。 这样&#xff0c;初学者的内容就更容易消化了。 首先&#xff0c;我将介绍有关Java的8种原始类型的所有信息。 Java基本类型 正…

androidtabhost缓存_FragmentTabHost布局的使用及优化方式

欢迎Follow我的GitHub, 关注我的简书. 其余参考Android目录.TabHostAndroidFragmentTabHost作为Android4.0版本的控件, 已经被项目广泛使用, 5.0版本又推出TabLayoutViewPager显示多页. 我来讲解如何使用FragmentTabHost.本文源码的GitHub下载地址主要包括:(1) 自定义Tab的图片…

二叉查找树

【0】README 0.1&#xff09;本文的重点在于介绍 二叉查找树的概念&#xff0c;以及写出 二叉查找树的操作例程的源代码&#xff0c; 其中当属delete 操作的源代码最不容易实现&#xff1b; 0.2&#xff09;本文源代码均为原创&#xff0c; 当然 代码中的idea 是借鉴人家的&a…

常用的命名规范/命名规则

文章目录骆驼式命名法&#xff08;CamelCase&#xff09;帕斯卡命名法&#xff08;PascalCase&#xff09;串式命名法&#xff08;KebabCase&#xff09;下划线命名法&#xff08;UnderScoreCase&#xff09;骆驼式命名法&#xff08;CamelCase&#xff09; 也叫小驼峰式命名法…

spring order_Spring @Order批注

spring order介绍&#xff1a; Spring Order注释是在Spring 2.0中首次引入的。 然后&#xff0c;它仅用于定义AspectJ建议中的顺序。 在Spring 4.0的后面&#xff0c;对该注释的实现进行了进一步改进。 从那时起&#xff0c;它还支持对Java数组或List之类的集合中的Spring组件或…

AVL树

【0】README 0.1&#xff09;本文给出了平衡二叉树&#xff08;AVL树&#xff09;的插入例程涉及到的单旋转双旋转的概念&#xff0c;并给出了代码实现&#xff1b; 0.2&#xff09;本文源代码均为原创&#xff0c; 当然相关idea 还是借鉴人家的&#xff1b;&#xff08;真心…

spring 注释_Spring@懒惰注释

spring 注释介绍&#xff1a; 默认情况下&#xff0c; Spring框架在应用程序启动时加载并热切初始化所有bean。 在我们的应用程序中&#xff0c;我们可能有一些非常消耗资源的bean。 我们宁愿根据需要加载此类bean。 我们可以使用Spring Lazy批注实现此目的 。 在本教程中&…

管理系统的账户设计(涉及注册/登录逻辑)

文章目录方案一方案二方案三方案一 类似华为云IAM&#xff08;Identity and Access Management 身份和访问管理&#xff09;用户&#xff0c;阿里云的 RAM&#xff08;Resource Access Management 资源访问管理&#xff09;用户 机构有独立的账户&#xff08;主账户&#xff…

opencv生成日志_OpenCV-Utils学习日志:VideoCapture使用样例

1.VideoCapture可以打开多种来源的数据流&#xff0c;但常见的是相机、视频及图像序列三类数据流&#xff1a;(1)打开相机数据流&#xff0c;需要指定相机在主机上的设备编号&#xff0c;若主机上只有一个相机则编号通常是0。(2)打开视频数据流&#xff0c;需要指定视频的完整路…

jdbc查询序列_JDBC –模拟序列

jdbc查询序列也许我们每个人在程序员的生活中至少遇到过一次这个问题- 如何模拟数据库序列&#xff1f; 在下面&#xff0c;您可能会发现我对该问题解决方案的各种了解。 假设我们有一个接口定义了所需的API&#xff0c;用于返回整数序列&#xff1a; public interface Sequen…

利用 GregorianCalendar 制作当前月的月历

【0】README 0.1&#xff09;本文文字总结于 core java volume 1 &#xff0c; 源代码均为原创&#xff1b; 0.2&#xff09;本文旨在熟悉 GregorianCalendar 日历类&#xff0c;每一天就是一个GregorianCalendar 日历类&#xff0c;一天有很多的日历属性&#xff0c;觉得用它…

pyecharts怎么绘制散点图_PyeCharts绘制各种图形

简介PyeCharts 是一个用于生成 Echarts 图表的类库&#xff0c;用其生成的图可视化效果非常棒&#xff0c;而且使用起来非常简单。下面是一些常用图的pyecharts实现方法柱状图bar pye.Bar("柱状图")#新建柱状图bar.add("服装", #图例名称["衬衫"…

junit junit_穿越JUnit流

junit junit关于JUnit 5迁移的好处之一是&#xff0c;您可以在老式模式下运行JUnit 4测试&#xff0c;并且所有内容仍然兼容。 不利的一面是&#xff0c;某些注释和方法在JUnit 4和JUnit 5中具有相同的名称&#xff0c;并且当两组库依赖项都可用时&#xff0c;很容易导入错误的…

被遗忘的软件产品形态

从2010年以后&#xff0c;很多公司开发的软件产品&#xff0c;很少有客户端了&#xff0c;web2.0之后&#xff0c;主流的业务系统基本上都是基于Web去构建业务系统。这几年见到的业务应用系统都是基于Web的构建的。而在To C市场&#xff0c;几乎就没有客户端了&#xff0c;都是…

vue进行判断使用class_vue判断dom的class

vue点击给dom添加class然后获取含有class的dom{{item.name}}{{item2.name}}jschek(index2, index) {this.iac[index2] indexthis.iac this.iac.concat([]);this.checkchose()},checkchose:function(){var chosethisvar chosedomchose.$refs.choseboxconsole.log(chosedom)for…

方法参数的值调用+引用调用+深浅拷贝

【0】README 0.1&#xff09;本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理清值调用引用调用&#xff1b; 【1】参数传递给方法的专业术语&#xff1a; 1.1&#xff09;值调用&#xff1a;它表示方法接收的是调用者提供的值&#xff1b; 1.2&#xff09;引用…

设计模式 工厂方法_工厂方法设计模式

设计模式 工厂方法工厂方法模式是流行的创作设计模式之一。 它并不特别依赖于工厂对象来创建对象。 而是要在同一类中使用单独的方法来创建对象。 Factory Method模式定义了一个用于创建对象的接口&#xff0c;但是让子类决定如何实例化其对象。 每个子类必须定义其Factory方法…