一、树的基本结构
树,是可以表示任意含有层次结构的数据结构。每棵树只有一个根结点,根结点下可以有任意的子结点,子结点又可以有任意个子结点,如此反复,若子结点下无子结点的子结点,则此结点称为叶,但每个结点只有一个父结点。
一下主要讨论的是二叉树,二叉树即每个结点最多有两个子结点。除根结点与叶结点外每个结点有父结点、子结点。对于构建一个二叉树的结点类,我们可定义四个属性,分别是:结点的数据、父结点、左子结点、右子结点。
/**
* 树的结点类
*
* @author lenovo
*
*/
public class TreeNode {
private Object obj; // 数据
private TreeNode parent; // 父结点
private TreeNode leftchild; // 左子结点
private TreeNode rightchild; // 右子结点
/**
* 重写构造方法
* @param obj
*/
public TreeNode(Object obj){
this.obj=obj;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getLeftchild() {
return leftchild;
}
public void setLeftchild(TreeNode leftchild) {
this.leftchild = leftchild;
}
public TreeNode getRightchild() {
return rightchild;
}
public void setRightchild(TreeNode rightchild) {
this.rightchild = rightchild;
}
}
二、树的三种遍历方式
对于一棵树,一般有三种遍历的方法,即前序遍历、中序遍历、后序遍历。前序遍历即先遍历父结点,再遍历左子结点,再右子结点;中序遍历即先遍历左子结点,再遍历父结点,再遍历右子结点;后序遍历即先遍历左子结点,再遍历右子结点,再遍历父结点
遍历一个棵树是否,采用哪种方式,主要看是先递归,还是先打印。
A
/ \
B C
/ / \
D E F
图
(1) 中序序列(inorder traversal)
中序遍历二叉树时,对结点的访问次序为中序序列
【例】中序遍历上图所示的二叉树时,得到的中序序列为:
D B A E C F
(2) 先序序列(preorder traversal)
先序遍历二叉树时,对结点的访问次序为先序序列
【例】先序遍历上图所示的二叉树时,得到的先序序列为:
A B D C E F
(3) 后序序列(postorder traversal)
后序遍历二叉树时,对结点的访问次序为后序序列
【例】后序遍历上图所示的二叉树时,得到的后序序列为:
D B E F C A
/**
* 遍历树的方法(左根右、根左右、左右根)
*
* @param root
* :树的根节点
*/
public void printTree(TreeNode root) {
if (root != null) {
// 前序(根左右)
// Object obj = root.getObj();
// System.out.println(obj);
// 左子结点递归
TreeNode leftTree = root.getLeftchild();
printTree(leftTree);
// 中序(左根右)
Object obj = root.getObj();
System.out.print(obj + "\t");
// 右子结点
TreeNode rightTree = root.getRightchild();
printTree(rightTree);
// 后序(左右根)
// Object obj = root.getObj();
// System.out.println(obj);
}
}
三、将数组用树表示,并实现有序的遍历输出(基于二叉搜索树的实现)
先定义一个根结点,从数组取小标为0的数据作为根结点(优化:将数组中的中值作为根结点)。每一次从数组中去一个数和根结点比较,若值小于根结点且子结点为null,则作为根结点的左子结点,若不为null,则对左子结点递归,若值大于或等于根结点且子结点为null,则作为根结点的右子结点,若不为null,则对右子结点递归。
/**
* 将数组转化为树的方法
*
* @param array
* @return
*/
public TreeNode arraytoTree(int[] array) {
if (array == null) {
throw new RuntimeException("传入的数组为空");
}
TreeNode ptree = new TreeNode(array[0]);
for (int i = 1; i < array.length; i++) {
DatatoTree(array[i],ptree);
}
return ptree;
}
/**
* 将数组中每个元素放入到树的方法 比根结点小的元素设为左子结点,比根结点大的元素设为右子结点
*
* @param num
* @param tree
* :根结点
*/
public void DatatoTree(int num, TreeNode root) {
// 如果值比根结点小的话,作为左子结点
if (num < (Integer) root.getObj()) {
if (root.getLeftchild() == null) { // 如果左子结点为null
TreeNode ltree = new TreeNode(num);
root.setLeftchild(ltree);
ltree.setParent(root);
} else { // 否则,左子结点递归
DatatoTree(num, root.getLeftchild());
}
// 如果值不比根结点小的话,作为右子结点
} else {
if (root.getRightchild() == null) { // 如果右子结点为null
TreeNode rtree = new TreeNode(num);
root.setRightchild(rtree);
rtree.setParent(root);
} else { // 否则,右子结点递归
DatatoTree(num, root.getRightchild());
}
}
}
分享到:
相关推荐
关于二叉树的程序,分别对无序数组和有序数组建立二叉树,实现遍历和查找。
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 将有序数组转换为二叉搜索树的结果肯定是不唯一的,因为存在...
用二叉查找树的方法对n个数进行排序,就是将这n个元素建立成一棵二叉查找树,再用中序遍历的函数遍历二叉树,就是对这些数的排序。建立一棵n个结点的二叉查找树的时间复杂度是O(n log n);在n个结点二叉查找树中...
树 * 字典树 ...* 二叉查找树-从有序数组中构造二叉查找树 * 二叉查找树-从有序链表构造平衡的二叉查找树 * 二叉树-的最大深度 数组&字符串 查找排序 排列组合 动态规划 树 链表 数学 位运算 编程之美
题目:数组A和数组B均有序,数组A有足够大内存来容纳数组B,将数组B有序合并到数组A中 分析:如果由前至后合并,复杂度将会是O(N2),这样的复杂度显然不是最优解,利用两个指针指向两个数组的尾部,从后往前遍历,...
经常会有人问我, PHP的数组, 如果用foreach来访问, 遍历的顺序是固定的么? 以什么顺序遍历呢? 比如: 复制代码 代码如下: <?php $arr[‘laruence’] = ‘huixinchen’; $arr[‘yahoo’] = 2007; $arr[‘baidu’] =...
示例 1:解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:示例 2:输出:[3,1]解释:[1,3] 和 [3,1] 都是高度平衡二
题目:将[0,1,2,3,4,5,6,7,8,9,10]存储到二叉树,原数组有序,转换为二叉排序树。 二叉排序树的特点:当前节点的左子树上的所有节点都小于该节点,右子树上的所有节点都小于该节点。 二叉排序也称为二叉查找树。 我...
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。如果是返回true,否则返回false。例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果. 8 / \ 6 10 / \ / \ 5...
图的广度优先遍历。c语言 VEXNODE adjlist[MAX_VEX]; /*定义头结点数组*/ int creatadjlist() /*建立邻接表*/ { ARCNODE *ptr; int arcnum,vexnum,k,v1,v2; printf("请输入顶点数和边数(输入格式为:顶点数,边数...
主要介绍了php判断一个数组是否为有序的方法,涉及php操作数组遍历的相关技巧,非常具有实用价值,需要的朋友可以参考下
js代码-有序数组在保持数组有序的情况下插入数字。 两种实现方式
(3)层次调节——以根结点为轴心,将树顺时针转动一定角度,使之层次分明。 2.森林转换成二叉树 (1)将森林中的每一棵二叉树转化成二叉树; (2)从第二课二叉树开始,依次把后一棵二叉树的根结点作为一棵二叉树根...
此类型在很多方面做了优化,因此可以把它当成真正的数组来使用,或列表(矢量),散列表(是图的一种实现),字典,集合,栈,队列以及更多可能性。因为可以用另一个 PHP 数 资源太大,传百度网盘了,链接在附件中,...
有序遍历 下一个申请页面 它包含2个输入字段,它们接受数组的长度和数组的元素。 它以成本O(1)的形式创建输入数组的链表,因为节点的值是该节点下一个属性的位置。 应用页面 将数组的长度和元素作为输入。
# 有序数组的平方 # 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减...# 截止条件定在为正负分界线上, 一旦达到表示其中一个数字遍历完毕, 剩下的直接进行追加即可
依次 比较 相邻的两个数,正序则不动,倒序则交换位置,如此循环,直到整个数组为有序为止 以下列数据为例: 第一轮比较 首先比较索引为0和1的值 3>2,为倒序 则进行位置交换 ↓↓↓↓↓↓↓ 再比较索引为1和2的...
题目链接解析思路1:直接遍历两个数组用两个指针 p1、p2 分别指向两个数组的首元素,将两个指针指向的较大的元素赋值给数组 nums1,若其中一个指针指向数组之
思考了一会发现也不是很难,假如数组是正序排列的,可以同时遍历2个数组,将小的值进行排序,最后会遍历完一个数组,留下一个非空数组,而且剩下的值肯定大于等于已经排好序的最大值. PHP代码: <?php function sort_...
解题思路:构建结构体数组存储数据(足够大的数组),利用数组本身的连续性将节点串接(此时非有序),然后遍历数组,按照数字地址确定链表节点的先后顺序,按先后顺序将链表节点的地址依次存入另一数组之中(此时...