ADT基础(二)—— Tree,Heap and Graph

1 Tree(二叉树)

  • 先根遍历 (若二叉树为空,则退出,否则进行下面操作)

    • 访问根节点
    • 先根遍历左子树
    • 先根遍历右子树
    • 退出

    访问顺序为:A、B、D、H、I、E、J、C、F、G

  • 中根遍历(若二叉树为空,则退出,否则进行下面操作)

    • 中根遍历左子树
    • 访问根节点
    • 中根遍历右子树
    • 退出

    访问顺序为:H、D、I、B、J、E、A、F、C、G

  • 后根遍历(若二叉树为空,则退出,否则进行下面操作)

    • 后根遍历左子树
    • 后根遍历右子树
    • 访问根节点
    • 退出

    访问顺序为:H、I、D、J、E、B、F、G、C、A

  • 广度优先遍历:

    访问顺序为:A、B、C、D、E、F、G、H、I、J

//链表表示
public class BinaryNode //节点类
{
Object element;
BinaryNode left; //lefft subtree
BinaryNode right; //right subtree
};
public class BinaryTree{ //节点树类
private BinaryNode root; public boolean isEmpty(){return root == null;}
//深度优先遍历,递归,非递归要用栈,而递归本质就是栈
public void PreOrder(BinaryNode node){ //先根遍历
if(node!=null){
System.out.println(node.element);
PreOrder(node.left);
PreOrder(node.right);
}
}
public void InOrder(BinaryNode node){ //中根遍历
if(node!=null){
InOrder(node.left);
System.out.println(node.element);
InOrder(node.right);
}
}
public void PostOrder(BinaryNode node){ //后根遍历
if(node!=null){
PostOrder(node.left);
PostOrder(node.right);
System.out.println(node.element);
}
}
//广度优先遍历,循环,使用队列
public void LevelOrder(BinaryNode node){
Queue q = new Queue();
while(node){
System.out.println(node.element);
if(node.left) q.add(node.left);
if(node.right) q.add(node.right);
try{ node = q.delete();} //弹出值赋给node
catch(OutOfBounds){return;}
}
}
} //清空
public void clear(BinaryNode node){ //清除某个子树的所有节点
if(node!=null){
clear(node.left);
clear(node.right);
node = null; //删除节点
}
}
public void clear(){ ////清空树
clear(root);
}
//求高度
public int height(BinaryNode node){ //获取以某节点为子树的高度
if(node==null){
return 0; //递归结束,空子树高度为0
}else{
//递归获取左子树高度
int l = height(node.left);
//递归获取右子树高度
int r = height(node.right);
//高度应该算更高的一边,(+1是因为要算上自身这一层)
return l>r? (l+1):(r+1);
}
}
public int height(){ //获取二叉树的高度
return height(root);
}
//求节点数
public int size(BinaryNode node){ //获取以某节点为子树的节点数
if(node==null){
return 0;
}else{
int l = size(node.left);
int r = size(node.right);
return l+r+1;
}
}
public int size(){ //获取二叉树的节点数
return size(root);
}
//返回某节点的父亲节点,这种二叉树只能递归地靠从根节点遍历来比较获取
public BinaryNode getParent(BinaryNode node,BinaryNode root){
if(root==null) retun null;
if(root.left==node||root.right==node) return root;
if(getParent(root.left,node)!=null) return getParent(root.left,node);
else return getParent(root.right,node);
}
public BinaryNode getParent(BinaryTreeNode node){
return (root==null||root==node)? null:getParent(root,node);
}
//已知前序和中序,重新构造二叉树
//核心:找到根节点,分开左右子树
//前序第一个就是根节点,以该点把中序分成左右两部分,左未左子树,右为右子树;同样,左右两部分,同上,递归
public void createBT(String pres,String ins,BinaryNode root){
int inpos;
String prestmp,instmp;
if(pres.length==0) root = null;
else{
root = new BinaryNode();
root.element = pres.charAt(0);
inpos = 0;
while(ins.charAt(inpos) != root.element) inpos++; //找到中序的树根 prestmp = pres.substring(1,inpos+1);
instmp = ins.substring(0,inpos); //左子树
createBT(pres,ins,t.left); //递归构造左子树 prestmp = pres.substring(inpos+1,pres.length()-1);
instmp = ins.substring(inpos+1,prs.length()-1); //左子树
createBT(pres,ins,t.right); //递归构造左子树
}
}
//已知后序与中序。算法同,相当于后序反过来找
//已知先序和后序,可以得到不唯一的树。核心:找到树根,分开左右子树
/*
先序遍历中刚遍历到的下一个节点是后序遍历中最后遍历的节点,所以可以将后序遍历拆分成两个子序列,从而进行递归构造。
例如 先序遍历为aebdc,后序遍历为bcdea。
首先可以确定根节点为a,在后序中找先序的下一个节点(也就是e),将原序列拆分成两部分,其左子树包含的元素有bcde,右子树为空。
接着在bcd中寻找先序中e的后一个元素即b的位置,将这个子序列又拆分成了b和cd两部分。如此递归下去就能得到一种可能的二叉树。
*/

2 Tree(二叉搜索树)

//查找
private BinaryNode find( Comparable x, BinaryNode t ){
if( t = = null ) return null;
if( x. compareTo( t.element ) < 0 ) return find( x, t.left );
else if( x.compareTo( t.element ) > 0 ) return find( x, t.right );
else return t; //Match
}
private BinaryNode findMin( BinaryNode t ){
if( t = = null ) return null;
else if( t.left = = null ) return t;
return findMin(t.left);
}
//递归或循环都可
private BinaryNode findMax( BinaryNode t ){
if( t != null )
while( t.right != null )
t = t.right;
return t;
}
//插入
private BinaryNode insert( Comparable x, BinaryNode t )
{
if( t == null )
t = new BinaryNode( x, null, null );
else if( x.compareTo( t.element ) < 0 )
t.left = insert( x, t.left );
else if( x.compareTo( t.element ) > 0 )
t.right = insert( x, t.right );
else ;//duplicate; do nothing
return t;
}
//删除
//三种情况:叶,只有一个非空子树的节点,有两个非空子树的节点
//用左子树的最大或右子树的最小(都是叶节点)来换,然后把左子树最大和右子树最小删除
private BinaryNode remove( Comparable x, BinaryNode t){
if( t == null ) return t;
if( x.compareTo( t.element ) < 0 )
t.left = remove( x, t.left );
else if( x.compareTo( t.element ) > 0 )
t.right = remove( x, t.right );
else if( t.left != null && t.right != null ){ //找到了
t.element = findMin( t.right ).element; //左子树max或右子树min
t.right = remove(t.element, t.right );
}else //左右子树一边为空或全为空,可以替换成左子树或右子树
t = ( t.left != null ) ? t.left : t.right;
}

ADT基础(二)—— Tree,Heap and Graph的更多相关文章

  1. 【数据结构05】红-黑树基础----二叉搜索树(Binary Search Tree)

    目录 1.二分法引言 2.二叉搜索树定义 3.二叉搜索树的CRUD 4.二叉搜索树的两种极端情况 5.二叉搜索树总结 前言 在[算法04]树与二叉树中,已经介绍过了关于树的一些基本概念以及二叉树的前中 ...

  2. Java面试题总结之Java基础(二)

    Java面试题总结之Java基础(二) 1.写clone()方法时,通常都有一行代码,是什么? 答:super.clone(),他负责产生正确大小的空间,并逐位复制. 2.GC 是什么? 为什么要有G ...

  3. Python全栈开发【基础二】

    Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...

  4. Bootstrap <基础二十九>面板(Panels)

    Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ...

  5. Bootstrap <基础二十八>列表组

    列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...

  6. Bootstrap<基础二十七> 多媒体对象(Media Object)

    Bootstrap 中的多媒体对象(Media Object).这些抽象的对象样式用于创建各种类型的组件(比如:博客评论),我们可以在组件中使用图文混排,图像可以左对齐或者右对齐.媒体对象可以用更少的 ...

  7. Bootstrap <基础二十六>进度条

    Bootstrap 进度条.在本教程中,你将看到如何使用 Bootstrap 创建加载.重定向或动作状态的进度条. Bootstrap 进度条使用 CSS3 过渡和动画来获得该效果.Internet ...

  8. Bootstrap <基础二十五>警告(Alerts)

    警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ...

  9. Bootstrap<基础二十四> 缩略图

    Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...

随机推荐

  1. Python爬虫笔记一(来自MOOC) Requests库入门

    Python爬虫笔记一(来自MOOC) 提示:本文是我在中国大学MOOC里面自学以及敲的一部分代码,纯一个记录文,如果刚好有人也是看的这个课,方便搬运在自己电脑上运行. 课程为:北京理工大学-嵩天-P ...

  2. vector的几种初始化及赋值方式

    转自https://www.cnblogs.com/quyc/p/12857054.html (1)不带参数的构造函数初始化 //初始化一个size为0的vector vector<int> ...

  3. 2015ACM/ICPC亚洲区沈阳站-重现赛 D - Pagodas

    题意:有\(n\)个数,开始给你两个数\(a\)和\(b\),每次找一个没出现过的数\(i\),要求满足\(i=j+k\)或\(i=j-k\),当某个人没有数可以选的时候判他输,问谁赢. 题解:对于\ ...

  4. 关于markdown的入门使用

    关于标题 方式一: 使用 = - 标示一,二级标题 = 表示一级标题 - 表示二级标题 示例: 我展示的是一级标题 ================= 我展示的是二级标题 -------------- ...

  5. 【转】REST风格框架实战:从MVC到前后端分离(附完整Demo)

    版权声明:欢迎转载,注明作者和出处就好!如果不喜欢或文章存在明显的谬误,请留言说明原因再踩哦,谢谢,我也可以知道原因,不断进步! https://blog.csdn.net/justloveyou_/ ...

  6. 四、Jmeter 集合点(实际场景应用)

    一.jmeter集合点的作用域及作用范围 先明确一些概念:1)定时器是在每个sampler(采样器)之前执行的,而不是之后: 是的,你没有看错,不管这个定时器的位置放在sampler之后,还是之下,它 ...

  7. 如何安装Gephi工具

    gephi中文版是一款开源免费跨平台基于JVM的复杂网络分析软件,安装后需要安装Java jdk API,否则就会出现gephi打不开的情况 该工具主要用于各种网络和复杂系统,动态和分层图的交互可视化 ...

  8. OpenStack Train版-2.安装keystone身份认证服务

    安装 keystone 认证 mysql -uroot create database keystone; grant all privileges on keystone.* to 'keyston ...

  9. 加密后的程序在Win8中无法运行

    需要使用dotNET_Reactor 4.7以上的版本加密后才能在Win8中使用.

  10. spring再学习之设计模式

    今天我们来聊一聊,spring中常用到的设计模式,在spring中常用的设计模式达到九种. 第一种:简单工厂 三种工厂模式:https://blog.csdn.net/xiaoddt/article/ ...