当前位置: 首页 > news >正文

双亲表示法构造树-----Java实现

package Data_Structure.Tree;

import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.Scanner;

//双亲表示法构造树,该树使用层序进行构造,通过parent下标索引双亲结点
public class ParentTree{
private static final int CAPACITY=100;
private Node nodes[];
private final int root;
private int length;

static class Node{private char data;private int parent;public Node(char data,int parent) {this.parent = parent;this.data = data;}public char getData(){return data;}public void setData(char val){this.data = val;}public int getParent(){return parent;}public void setParent(int index){}
}//构造函数,给数组分配内存
public ParentTree(){nodes  = new Node[CAPACITY];root=0;length=0;
}//构造树结构, 输入时,按照层序排序输入
public void createTree(int n) throws IOException {if(n<=0||n>CAPACITY)throw new IllegalArgumentException("非法参数:"+ n);Scanner in =new Scanner(System.in);System.out.println("请先输入根结点元素:");nodes[0] = new Node(in.next().charAt(0),-1); //根结点没有双亲结点clearCacheArea(); //清空缓存区length++;System.out.println("输入子结点以及对应双亲结点的索引\n字符与数字输入完后回车再输入下一对");for(int i=1;i<n;i++){nodes[i] = new Node((char)System.in.read(),in.nextInt());clearCacheArea();length++;}
}//根据传入数组构造树
public void createTree(int n,char[] data,int[] parents){if(n>CAPACITY || n<=0 || data.length!= parents.length && data.length!=n)throw new IllegalArgumentException("非法参数");for(int i=0;i<n;i++){nodes[i] = new Node(data[i],parents[i]);length++;}
}public void show(){if(length<=0)throw new NoSuchElementException("无元素");for(int i=0;i<length;i++){System.out.println(nodes[i].data+": 双亲结点 "+ nodes[i].parent);}
}//清空输入缓存区
public static void clearCacheArea() throws IOException {while (System.in.available() > 0) {System.in.read();}
}// 清空该树
public void clearTree(){nodes=new Node[CAPACITY]; //分配新的内存length=0;}//判断树是否为空
public boolean treeEmpty(){return this.length == 0;
}//返回T的根结点元素
public char root(){return nodes[0].data;
}//返回树的结点数
public int getLength()
{return this.length;
}// 返回树的深度
public int treeDepth(){if(length==0)return 0;int depth=0;/*我设计让nodes[0]始终存储的为根结点所以,从下往上遍历即从数组最后一个元素往前找* *///从叶子结点往上遍历for(int i=length-1;i>=0;i--){int curDepth=0;int cursor =i; // 游标,根据当前节点的parent往上爬while(cursor!=-1){ // 如果游标不等于根结点cursor = nodes[cursor].getParent(); //就记录当前游标结点的双亲结点索引,往上爬curDepth++; //深度+1}if(curDepth>depth)depth = curDepth;}return depth;
}//返回指定结点的值
public char value(int index){if(index <0 ||index>=getLength())throw new ArrayIndexOutOfBoundsException(index +"out bound");return nodes[index].getData();
}// 赋予指定结点新值 ,并返回旧的值
public char assign(int index ,char val){if(index <0 ||index>=getLength())throw new ArrayIndexOutOfBoundsException(index +"out bound");char oldValue = nodes[index].getData();nodes[index].setData(val);return oldValue;
}//返回指定索引的双亲结点的元素
public char parent(int index ){if(index <0 ||index>=getLength())throw new ArrayIndexOutOfBoundsException(index +"out bound");if(index==0)throw new NoSuchElementException("根结点没有双亲");return nodes[nodes[index].getParent()].getData();
}// 返回指定索引的最左孩子结点data域
public char leftChild(int index){if(index<0 ||index >=length)throw new ArrayIndexOutOfBoundsException(index+"使数组溢出");//从最头开始找/*条件为,该结点的双亲结点索引 == index* 并且是第一个* */for(int i=0;i<length;i++){if(nodes[i].getParent()==index)return nodes[i].getData();}//循环结束就代表没找到,返回-return ' ';
}// 返回指定索引的最右孩子结点data域
public char rightChild(int index){if(index<0 ||index >=length)throw new ArrayIndexOutOfBoundsException(index+"使数组溢出");//从最尾开始找/*条件为,该结点的双亲结点索引 == index* 并且是第一个* */for(int i=length-1;i>=0;i--){if(nodes[i].getParent()==index)return nodes[i].getData();}//循环结束就代表没找到,返回-return ' ';
}// 双亲表示符实现插入和删除比较复杂,且不符合设计理论,双亲表示法适合需大量查询父节点的场景
// 且双亲表示法本身就是用静态数组表示,若你插入后,移动了数组,parent将全部失效,需要考虑的地方很多public static void main(String[] args) throws IOException {ParentTree tree = new ParentTree();//测试时的数据char[] data = {'R','A','B','C','D','E','F','G','H','K'};int[] parents = {-1,0,0,0,1,1,3,6,6,6};tree.createTree(10,data,parents);tree.show();System.out.println("tree的结点数为:"+ tree.getLength());System.out.println("tree的深度为:" + tree.treeDepth());System.out.println("tree的根结点为:"+tree.root());System.out.println("tree位于"+5+"索引的数据为"+tree.value(5));char val =  'O';System.out.println("为索引"+6+"的结点赋新值,它的旧值为:"+tree.assign(6,val));tree.show();System.out.println("索引1的双亲结点元素为"+tree.parent(1));System.out.println("索引为1的结点的左孩子为 "+tree.leftChild(1));System.out.println("索引为1的结点的右孩子为 "+tree.rightChild(1));System.out.println("索引为2的结点的右孩子为 "+tree.rightChild(2));}

}

http://www.jsqmd.com/news/299095/

相关文章:

  • KiCad V10新特性前瞻
  • 电气设计的隐藏外挂:1:1元器件图库实战
  • 基于传统材料力学势能法的健康齿轮时变啮合刚度数值分析
  • Product Hunt 每日热榜 | 2026-01-25
  • 构建 OpenHarmony 跨设备任务协同中心:Flutter 实现多端任务流转与状态同步
  • 构建 OpenHarmony 智能场景自动化配置面板:Flutter 实现可视化规则编排
  • Simulink双Y-30度六相感应电机模型,matlab18B版本。 六相交流供电
  • 强烈安利8个一键生成论文工具,继续教育学生论文写作必备!
  • ubuntu_server安装教程
  • 基于深度学习的 pcb 缺陷检测系统
  • 基于单片机的汽车倒车雷达超声波测距系统设计
  • 2025年市面上热门的自动化立体库制造企业怎么选,轻型货架/隔板货架/仓储货架/中型货架,自动化立体库供应厂家哪家强
  • JWT 解码工具
  • 基于深度学习的电动车头盔检测系统
  • keycloak测试11.0.2 for windows
  • 基于深度学习的番茄检测系统
  • 基于深度学习的肺部病变检测系统
  • 得到节点Device (P2P0)的子节点Device (S1F0)的PCI地址
  • 导师严选2026继续教育一键生成论文工具TOP9:学术写作全维度测评
  • 开源DTU全套方案详解:原理图设计、PCB布局、BOM清单、上位机源码及Keil嵌入式源码集成
  • 基于MATLAB的TERCOM算法实现与优化
  • 小红书高清/4K视频下载指南(2026最新实测有效)
  • 电子标签拣货系统:高效、智能的物流分拣解决方案
  • 这群程序员疯了,不给钱的活都干
  • 珲春推荐一下烤肉哪家正宗
  • 珲春推荐烤肉哪家无广
  • MATLAB算法仿真:无人机系统三维地图路径规划 - 多种算法对比(包括BA、CPFIBA和D...
  • 基于Matlab-YALMIP-CPLEX的微网优化调度:‘总费用最低‘的蓄电池与市场购售电功...
  • 贾子战略 - 军事理论体系的深度解构与时代价值洞察
  • 揭秘优质大牌美妆小样供应链,这几点是关键,服务好的大牌美妆小样供应链哪个好精选国内优质品牌榜单