ADT基础(二)—— Tree,Heap and Graph
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的更多相关文章
- 【数据结构05】红-黑树基础----二叉搜索树(Binary Search Tree)
目录 1.二分法引言 2.二叉搜索树定义 3.二叉搜索树的CRUD 4.二叉搜索树的两种极端情况 5.二叉搜索树总结 前言 在[算法04]树与二叉树中,已经介绍过了关于树的一些基本概念以及二叉树的前中 ...
- Java面试题总结之Java基础(二)
Java面试题总结之Java基础(二) 1.写clone()方法时,通常都有一行代码,是什么? 答:super.clone(),他负责产生正确大小的空间,并逐位复制. 2.GC 是什么? 为什么要有G ...
- Python全栈开发【基础二】
Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...
- Bootstrap <基础二十九>面板(Panels)
Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ...
- Bootstrap <基础二十八>列表组
列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...
- Bootstrap<基础二十七> 多媒体对象(Media Object)
Bootstrap 中的多媒体对象(Media Object).这些抽象的对象样式用于创建各种类型的组件(比如:博客评论),我们可以在组件中使用图文混排,图像可以左对齐或者右对齐.媒体对象可以用更少的 ...
- Bootstrap <基础二十六>进度条
Bootstrap 进度条.在本教程中,你将看到如何使用 Bootstrap 创建加载.重定向或动作状态的进度条. Bootstrap 进度条使用 CSS3 过渡和动画来获得该效果.Internet ...
- Bootstrap <基础二十五>警告(Alerts)
警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ...
- Bootstrap<基础二十四> 缩略图
Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...
随机推荐
- hdu 1541 (cdq分治)
Problem Description Astronomers often examine star maps where stars are represented by points on a p ...
- Codeforces Round #656 (Div. 3) B. Restore the Permutation by Merger
题目链接:https://codeforces.com/contest/1385/problem/B 题意 有两个大小为 $n$ 的相同的排列,每次从二者或二者之一的首部取元素排入新的数组,给出这个大 ...
- URAL - 1635 哈希区间(或者不哈希)+dp
题意: 演队在口试中非常不幸.在42道考题中,他恰好没有准备最后一道题,而刚好被问到的正是那道题.演队坐在教授面前,一句话也说不出来.但教授心情很好,给了演队最后一次通过考试的机会.他让这个可怜的学生 ...
- 恢复win10 LTSC 2019 图片查看器功能
1.开始–运行–输入"regedit"打开注册表. 2. 在打开的注册表编辑器中,从左侧依次展开:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Win ...
- Chrome Switchs & Chrome Pref
Chrome Switchs: https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_switche ...
- CentOS 7 升级内核版本
1.查看当前内核版本 $ uname -r 3.10.0-514.el7.x86_64 $ uname -a Linux k8s-master 3.10.0-514.el7.x86_64 #1 SMP ...
- 关于TCP状态TIME_WAIT的理解
1.TIME_WAIT的作用: TIME_WAIT状态存在的理由:1)可靠地实现TCP全双工连接的终止 在进行关闭连接四次挥手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器 ...
- μC/OS-III---I笔记7---消息队列
消息队列 任务之间仅仅靠信号量进行"沟通"是不够的,信号量可以标志事件的发生,却无法传递更多的数据,在需要任务间的数据信息传递时就绪要用到消息队列,传统我们一般在前后太系统中都是通 ...
- 买车交税 All In One
中国买车交税 All In One 消费税 增值税 车辆购置税 车船税 关税 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问! 原 ...
- 2015 - 2020 最新 Linux 命令大全
# 2015 - 2020 最新 Linux 命令大全 ## VIM 命令模式(Command mode):vi 插入模式(Insert mode):i底线命令模式(Last line mode):e ...