顺序储存二叉树
public class welltree {
public static void main(String[] args) {
int []x = {1,2,3,4,5,6,7};
tree1 t = new tree1(x);
// t.preOrder(0);//前序遍历
// t.fixOrder(0);//中序遍历
t.lastOrder(0);//后序遍历
}
}
//顺序存储二叉树
class tree1{
private int []arr;
public tree1(int []x){
arr = x;
}
//通过传入的索引在树中的位置开始前序遍历
public void preOrder(int index){
//查看数组内是否为空 和数组是否被使用
if (arr==null&&arr.length==0){
System.out.println("无数据");
}else{
//输出当前节点
System.out.println(arr[index]);
//防止越界 判断当前节点有没有左子节点
if (index*2+1 < arr.length){
//如果有以当前节点的左子节点为根节点进行前序遍历
preOrder(index*2+1);
}
//同上 这个是右子节点
if (index*2+2 < arr.length){
preOrder(index*2+2);
}
}
}
//通过传入的索引在树中的位置开始中序遍历
public void fixOrder(int index){
//查看数组内是否为空 和数组是否被使用
if (arr==null&&arr.length==0){
System.out.println("无数据");
}else{
//防止越界 判断当前节点有没有左子节点
if (index*2+1 < arr.length){
//如果有以当前节点的左子节点为根节点进行中序遍历
fixOrder(index*2+1);
}
//输出当前节点
System.out.println(arr[index]);
//同上 这个是右子节点
if (index*2+2 < arr.length){
fixOrder(index*2+2);
}
}
}
//通过传入的索引在树中的位置开始后序遍历
public void lastOrder(int index){
//查看数组内是否为空 和数组是否被使用
if (arr==null&&arr.length==0){
System.out.println("无数据");
}else{
//防止越界 判断当前节点有没有左子节点
if (index*2+1 < arr.length){
//如果有以当前节点的左子节点为根节点进行后序遍历
lastOrder(index*2+1);
}
//同上 这个是右子节点
if (index*2+2 < arr.length){
lastOrder(index*2+2);
}
//输出当前节点
System.out.println(arr[index]);
}
}
}
线索化二叉树
public class treeTest {
public static void main(String[] args) {
//创建节点
node node1 = new node(1,"阿狸");
node node2 = new node(2,"剑圣");
node node3 = new node(3,"亚索");
node node4 = new node(4,"盖伦");
node node5 = new node(5,"卡特");
node node6 = new node(6,"螳螂");
//建立树的关系
tree tree = new tree();
//设置根节点
tree.setnode(node1);
//设置节点的左节点和右节点
node1.setLeft(node2);
node1.setRight(node3);
node2.setLeft(node4);
node2.setRight(node5);
node3.setLeft(node6);
preOrderTree preOrderTree = new preOrderTree();
preOrderTree.setRoot(node1);
// //前序遍历 先当前节点 然后当前节点的左节点 然后右节点
// System.out.println("前序遍历");
// tree.preOrder();
// //中序遍历 先当前节点的左节点 再当前节点 然后右节点
// System.out.println("中序遍历");
// tree.fixOrder();
// //后序遍历 先当前节点的左节点 然后右节点 再当前节点
// System.out.println("后序遍历");
// tree.lastOrder();
// System.out.println("前序查找");
// node cz1 = tree.preOrderSearch(4);
// System.out.println(cz1);
// System.out.println("中序查找");
// node cz2 = tree.fixOrderSearch(4);
// System.out.println(cz2);
// System.out.println("后序查找");
// node cz3 = tree.lastOrderSearch(4);
// System.out.println(cz3);
// System.out.println("删除节点前 - 前序遍历");
// tree.preOrder();
// //删除节点
// tree.delete(3);
// System.out.println("删除节点后 - 前序遍历");
// tree.preOrder();
preOrderTree.qxtree();//线索化
System.out.println(node5.getLeft());
System.out.println(node5.getRight());
System.out.println("遍历前序线索化树");
preOrderTree.qxTreeb();
}
}
//创建前序线索二叉树
class preOrderTree{
private node pre = null;//在线索化的时候用来储存前驱节点
private node root;//根节点
//设置根节点
public void setRoot(node root){
this.root = root;
}
public preOrderTree(){
qxtree(root);
}
//重载 这样调用方法时就不需要自己传跟根节点了
public void qxtree(){
qxtree(this.root);
}
//前序线索化二叉树
public void qxtree(node root){
//防止空节点
if (root==null){
return;
}
// System.out.println(root);
// if (root.getLeft()!=null){
// }
// System.out.println(root);
//因为是前序 先线索化当前节点
// System.out.println("root: "+root);
System.out.println("pre: "+pre);
if (root.getLeft()==null){
root.setLeft(pre);
// System.out.println(root);
root.setLeftType(true);
}
if (pre!=null&&pre.getRight()==null){
pre.setRight(root);
// System.out.println(pre+" "+pre.getRight());
pre.setRightType(true);
}
pre = root;
// if (root.getRight()!=null){
//切记记得判断当前节点是不是被设置过前驱或者后继 不然会死循环!!!
if (!root.isLeftType()) {
qxtree(root.getLeft());
}
if (!root.isRightType()) {
qxtree(root.getRight());
}
// }
// System.out.println(pre);
// System.out.println(root);
}
//前序线索化树的遍历
public void qxTreeb(){
//节点不能为空
if (root==null){
return;
}
//辅助变量 用来帮助遍历
node sign = root;
//当辅助变量的值不为null 就一直循环
while (sign!=null){
//当辅助变量当前值的左子节点不为空 并且他的左子节点不是代表他的前驱的时候循环
while (sign.getLeft()!=null&& !sign.isLeftType()){
System.out.println(sign);
sign = sign.getLeft();
}
//输出当前sign代表的节点的值
System.out.println(sign);
//如果当前节点的左子节点代表的是他的前驱 那么跳过这个节点
if (sign.isLeftType()){
sign = sign.getRight();
}
//当sign的值不为null并且sign的右边代表的是他的后继的时候循环
while (sign!=null&&sign.isRightType()){
System.out.println(sign);
sign = sign.getRight();
}
}
}
}
//创建树
class tree{
//创建一个根节点
private node nodex;
//接受根节点
public void setnode(node node){
this.nodex = node;
}
//前序遍历
public void preOrder(){
if (this.nodex !=null){
this.nodex.preOrder();
}else{
System.out.println("树空!");
}
}
//中序遍历
public void fixOrder(){
if (this.nodex !=null){
this.nodex.fixOrder();
}else{
System.out.println("树空!");
}
}
//后序遍历
public void lastOrder(){
if (this.nodex !=null){
this.nodex.lastOrder();
}else{
System.out.println("树空!");
}
}
//前序查找
public node preOrderSearch(int i){
//如果根节点不为空
if (nodex!=null){
//返回 以当前根节点为根节点的前序查找方法的返回值
return nodex.preOrderSearch(i);
}else{
//如果根节点都为null 那么返回null
return null;
}
}
//中序查找
public node fixOrderSearch(int i){
if (nodex!=null){
return nodex.fixOrderSearch(i);
}else{
return null;
}
}
//后序查找
public node lastOrderSearch(int i){
if (nodex!=null){
return nodex.lastOrderSearch(i);
}else{
return null;
}
}
//删除节点
public void delete(int i){
if (nodex!=null){
if (nodex.getId()==i){
nodex = null;
}else{
nodex.delete(i);
}
}else{
System.out.println("树空!");
}
}
}
//创建数的节点
class node{
private int id;//编号
private String name;//名称
private node left;//左子节点
private node right;//右子节点
private boolean leftType = false;//用来编辑当前节点的左指针域链接的是 左子节点 还是他的前驱
private boolean rightType = false;//用来编辑当前节点的右指针域链接的是 右子节点 还是他的后继
//构造节点
public void setRightType(boolean rightType) {
this.rightType = rightType;
}
public boolean isRightType() {
return rightType;
}
public boolean isLeftType() {
return leftType;
}
public void setLeftType(boolean leftType) {
this.leftType = leftType;
}
public node(int id, String name){
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
//设置左子节点
public void setLeft(node left) {
this.left = left;
}
//设置右子节点
public void setRight(node right) {
this.right = right;
}
//获取左子节点
public node getLeft() {
return left;
}
//获取右子节点
public node getRight() {
return right;
}
//重写tostring方法
@Override
public String toString() {
return "node{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
//前序遍历二叉树
public void preOrder(){
//根节点
//this就是你是通过那个节点调用的这个方法那么this就是那个节点
System.out.println(this);
//如果左子节点不为空
if (this.left!=null){
//那么继续以当前左子节点为根节点的前序遍历
this.left.preOrder();
}
//如果右子节点不为空
if (this.right!=null){
//同上
this.right.preOrder();
}
}
//中序遍历二叉树
public void fixOrder(){
//如果左子节点不为空
if (this.left!=null){
//那么继续以当前左子节点为根节点的前序遍历
this.left.fixOrder();
}
//根节点
//this就是你是通过那个节点调用的这个方法那么this就是那个节点
System.out.println(this);
//如果右子节点不为空
if (this.right!=null){
//同上
this.right.fixOrder();
}
}
//后序遍历二叉树
public void lastOrder(){
//如果左子节点不为空
if (this.left!=null){
//那么继续以当前左子节点为根节点的前序遍历
this.left.lastOrder();
}
//如果右子节点不为空
if (this.right!=null){
//同上
this.right.lastOrder();
}
//根节点
//this就是你是通过那个节点调用的这个方法那么this就是那个节点
System.out.println(this);
}
//前序查找
public node preOrderSearch(int i){
//标记 用来判断是否找到了目标
node sign = null;
//如果当前节点的id=目标id
//这个消息输出了几次 就代表通过几个节点找到的 注意位置要在判断this.id的地方的前面 只有这个是在判断是否符合条件
System.out.println("前序查找次数验证");
if (this.id==i){
//那么返回这个节点
return this;
}
//如果当前节点的左子节点不为空
if (this.left!=null){
//那么sign标记就 = 以当前节点的左子节点为跟再前序查找目标的返回值
sign = this.left.preOrderSearch(i);
}
//如果标记被改变了 不为null了 那么返回他自己结束方法
if (sign!=null){
return sign;
}
if (this.right!=null){
sign = this.right.preOrderSearch(i);
}
//到了这里无论是否找到都返回sign的值
return sign;
}
//中序查找
public node fixOrderSearch(int i){
node sign = null;
if (this.left!=null){
sign = this.left.fixOrderSearch(i);
}
if (sign!=null){
return sign;
}
System.out.println("中序查找次数验证");
if (this.id==i){
return this;
}
if (this.right!=null){
sign = this.right.fixOrderSearch(i);
}
return sign;
}
//后序查找
public node lastOrderSearch(int i){
node sign = null;
if (this.left!=null){
sign = this.left.lastOrderSearch(i);
}
if (sign!=null){
return sign;
}
if (this.right!=null){
sign = this.right.lastOrderSearch(i);
}
if (sign!=null){
return sign;
}
System.out.println("后序查找次数验证");
if (this.id==i){
return this;
}
return sign;
}
//通过id来删除对应的节点
public void delete(int i){
//因为删除节点的特殊性 想删除一个节点必须通过他的上一个节点所以这里判断的都是.next
if (this.left!=null&&this.left.id==i){
this.left = null;
return;
}
if (this.right!=null&&this.right.id==i){
this.right = null;
return;
}
//如果当前节点的左右子节点都不是目标节点 那么就分别以当前左子节点为根节点继续删 和以右..
if (this.left!=null){
this.left.delete(i);
}
if (this.right!=null){
this.right.delete(i);
}
}
}