顺序存储二叉树
如果你的生活已处于低谷,那就大胆走,因为你怎样走都是在向上。
1. 树(Tree)


上面第二个图当中的A为根节点,同时A为B和C的父节点,B和C为A的子节点,同时,B和C是兄弟节点,没有子节点的节点为叶节点
- 树的三个相似概念:深度,高度,层

- 节点的高度 = 节点到叶子节点的最长路径(边数)
- 节点的深度 = 根节点到这个节点所经历的边的个数
- 节点的层数 = 节点的深度 + 1
- 树的高度 = 节点的高度
2.二叉树(Binary Tree)
二叉树的每个节点最多有两个子节点,分别为左子节点和右子节点。
-
满二叉树:叶子节点全都在最底层,除了叶子节点之外,每个节点都有左右子节点;
-
完全二叉树:叶子节点全都在最底下的两层,最后一层叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大;
-
顺序存储二叉树
从数据存储来看,数组存储方式和数的存储方式可以相互转换,即数组可以转换成树,数也可以转换成数组;

顺序存储二叉树的特点: -
顺序存储二叉树通常只考虑完全二叉树
-
第n个元素的左子节点为2*n+1
-
第n个元素的右子节点为2*n+2
-
第n个元素的父节点为(n-1)/ 2
-
n:表示二叉树中的第几个元素(按0开始编号)
完整代码:
public class ThreadedBinaryTreeDemo {
public static void main(String[] args) {
//测试中序线索二叉树的功能
HeroNode root = new HeroNode(1, "Tom");
HeroNode node2 = new HeroNode(3, "Jack");
HeroNode node3 = new HeroNode(6, "Smith");
HeroNode node4 = new HeroNode(8, "Mary");
HeroNode node5 = new HeroNode(10, "King");
HeroNode node6 = new HeroNode(14, "Dim");
//二叉树,后面我们要递归创建,现在简单处理使用手动创建
root.setLeft(node2);
root.setRight(node3);
node2.setLeft(node4);
node2.setRight(node5);
node3.setLeft(node6);
//测试中序线索化
ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree();
threadedBinaryTree.setRoot(root);
threadedBinaryTree.threadedNodes();
//当线索二叉树后,不能在使用原来的遍历方法
System.out.println("使用线索化的方式遍历,线索化二叉树");
threadedBinaryTree.threadedList();
}
}
//定义TreadedBinaryTree实现了线索化功能的二叉树
class ThreadedBinaryTree{
private HeroNode root;
//为了实现线索化,需要创建要指向当前节点的前驱节点的指针
//在递归进行线索化时,pre总是保留前一个节点
private HeroNode pre = null;
public void setRoot(HeroNode root) {
this.root = root;
}
//重载一把treadedNode方法
public void threadedNodes(){
this.threadedNodes(root);
}
//遍历线索化二叉树的方法
public void threadedList(){
//定义一个变量,存储当前遍历的节点,从root开始
HeroNode node = root;
while (node != null){
//循环的找到leftType==1的节点
//后面随着遍历而变化,因为当leftType==1时,说明该节点是按照线索化
//处理后的有效节点
while (node.getLeftType()==0){
node = node.getLeft();
}
//打印当前这个节点
System.out.println(node);
//如果当前节点的右指针指向的是后继节点,就一直输出
while (node.getRightType()==1){
//获取到当前节点的后继节点
node = node.getRight();
System.out.println(node);
}
//替换这个遍历的节点
node = node .getRight();
}
}
//编写对二叉树进行中序线索化的方法
/**
*
* @param node 就是当前需要线索化的节点
*/
public void threadedNodes(HeroNode node){
//如果node==null,不能线索化
if (node ==null){
return;
}
//①先线索化左子树
threadedNodes(node.getLeft());
//②线索化当前节点
//处理当前节点的前驱节点
if (node.getLeft()==null){
//让当前节点的左指针指向前驱节点
node.setLeft(pre);
//修改当前节点的左指针的类型,指向前驱节点
node.setLeftType(1);
}
//处理后继节点
if (pre!=null && pre.getRight()==null){
//让前驱节点的右指针指向当前节点
pre.setRight(node);
//修改前驱节点的右指针类型
pre.setRightType(1);
}
//每处理一个节点后,让当前节点是下一个节点的前驱节点
pre= node;
//③再线索化右子树
threadedNodes(node.getRight());
}
}
class HeroNode{
private int no;
private String name;
private HeroNode left;
private HeroNode right;
//说明
//如果leftType==0表示指向的是左子树,如果1则指向前驱节点
//如果rightType==0表示指向的是右子树,如果1则指向后继节点
private int leftType;
private int rightType;
public int getLeftType() {
return leftType;
}
public void setLeftType(int leftType) {
this.leftType = leftType;
}
public int getRightType() {
return rightType;
}
public void setRightType(int rightType) {
this.rightType = rightType;
}
public HeroNode(int no, String name) {
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name +
'}';
}
}
本文介绍了树的基本概念,包括节点的深度、高度和层,并深入讲解了二叉树,特别是完全二叉树的概念。顺序存储二叉树通过数组表示,其中每个元素的左子节点为2*n+1,右子节点为2*n+2,父节点为(n-1)/ 2,这种存储方式便于转换和操作。
&spm=1001.2101.3001.5002&articleId=115647767&d=1&t=3&u=c2ea5476080f4435ba87419332857d12)
271

被折叠的 条评论
为什么被折叠?



