二叉树:
基本性质
用链表表示二叉树
用数组表示二叉树
树形结构的特点是一个节点可以有多个后继是一种常用的非线性结构
树定义:
树是N(N>=0)个节点的有穷集合:满足:
有且仅有一个称为根的节点
其余节点分为m(m>=0)个互不相交的非空集合T1 T2...TM,这些集合中的每一个都是一棵树
称为根的子树
树的相关名称及意义:
叶节点或终端节点:一棵树中没有子节点的节点称为:叶子节点
父节点和子节点:若节点X一个以节点Y为树根子树,则X为Y的父节点,而Y为X的子节点
祖先:
由某个节点X到根节点的路径上的所有节点,成为X的祖先
根节点:
一棵树中没有父节点的节点,称为节点
非终端节点:除了叶节点与根节点以外的其他节点,称为非终端节点。
兄弟:同为一个父节点的节点,称为兄弟。
阶层:
阶层为节点的特性值,将根节点的阶层设为1,其子节点为2,一次类推
树林:
N》=0个树集合称为树林。若将一棵树的根节点移去,所剩下的恰是一个森林
分支度:
每个节点所拥有的子节点个数,而一棵树中分支度值为其最大分之度。
高度或深度:
一棵树中的最大阶层值,称为数的高度或深度
树及二叉树结合了有序树组合链表俩种数据结构的优点
在树中查找数据在数组中查找一样快
在树中添加删除数据的速度也和在链表中一样快
二叉树是树的一种
由有限个节点所构成的集合,此集合可以为空的
二叉树的根节点下可分成俩个子树,称为左子树和右子树
左子树和右子树亦是二叉树
二叉树的子树是有顺序关系,所以结构相同的俩棵树也是不用的二叉树。
二叉树具有的性质
二叉数第 i (i>=1)层上至多有2^(i-1)个节点
深度为k(k>1)的二叉树至多有2^k -1个节点
对任何二叉树,若2度节点数为n2,则子叶数n0=n2+1
二叉树与树的区别
二叉树可为空,而树不可以(至少要有根节点)
二叉树的子树有顺序关系,而数没有
二叉树的分支度比为0,1,2 而树的分之度可以大于2
歪斜树
:在一棵树中,若所有节点的左子树均不存在,则此树为右歪斜树
若所有节点的右子树均不存在,则此树为左歪斜树
满二叉树
一棵树中所有的节点均在同一阶层,而其他非终端节点的分度均为2则此树
为一个满二叉树,若该树的高度为h,则此二叉树的节点为2^h-1
完全二叉树
如果在一棵树深度为K(k>=1)的满二叉树上删去第K层上最右的连续J(0<=j<=2^(k-1))个节点
就得到一颗深度为K的完全二叉树
特点:
叶子节点只能在层次最大的俩层上出现,对任一节点,若其右下分支子孙的最大层次为1,
则其左分子下子孙的最大层次必须为1或2
二叉树:的遍历通常分为三个任务
1访问根节点
2)遍历左子树(既依次遍历左子树上的所有节点)
3)遍历右子树(既依次遍历右子树上的所有节点)
先根遍历(先访问根节点 左孩子 右孩子)
访问根节点,先根遍历左子树,先跟遍历右子树
中根遍历(先访问左孩子 根节点 右孩子)
中根遍历左子树,访问根节点,中根遍历右子树
后根遍历(先左后右在中间)
后根遍历左子树,后根遍历右子树,问根节点
假设父节点的编号为i
则:左子节点为父节点乘以2:2*i
右子节点为父节点乘以2加12*i+1
用链表来实现
public class Node {
int data;
Node leftChild;
Node rightChild;
public Node(int data) {
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
}
package Binary.Tree;
public class BTree {
//根节点
Node root;
public BTree(int data) {
root=new Node(data);
}
//新增节点
public void addNode(int data) {
//获取根节点
Node p=root;
//生成新节点
Node t=new Node(data);
while(true) {
//放到根节点的左边
if(p.data>data) {
if(p.leftChild!=null) {
//继续往下找
p=p.leftChild;
}else {
p.leftChild=t;
break;
}
//访问根节点右边
}else {
if(p.rightChild!=null) {
p=p.rightChild;
}else {
p.rightChild=t;
break;
}
}
}
}
//遍历先序遍历
//10 8 7 3 1 -10 6 20 90 100
public void predisPlay(Node root) {
System.out.println(root.data);
if(root.leftChild!=null) {
predisPlay(root.leftChild);
}
if(root.rightChild!=null) {
predisPlay(root.rightChild);
}
}
//中序遍历
//-10 1 3 6 7 8 10 20 90 100
public void disPlay(Node root) {
if(root.leftChild!=null) {
disPlay(root.leftChild);
}
System.out.println(root.data);
if(root.rightChild!=null) {
disPlay(root.rightChild);
}
}
//后续遍历
//-10 1 6 3 7 8 100 90 20 10
public void reardisPlay(Node root) {
if(root.leftChild!=null) {
reardisPlay(root.leftChild);
}
if(root.rightChild!=null) {
reardisPlay(root.rightChild);
}
System.out.println(root.data);
}
public static void main(String[] args) {
BTree tree = new BTree(10);
//10 8 7 20 90 100 3 6 1 -10
tree.addNode(8);
tree.addNode(7);
tree.addNode(20);
tree.addNode(90);
tree.addNode(100);
tree.addNode(3);
tree.addNode(6);
tree.addNode(1);
tree.addNode(-10);
System.out.println("先序遍历的结果为"+"==============");
tree.predisPlay(tree.root);
System.out.println("中序遍历的结果为"+"==============");
tree.disPlay(tree.root);
System.out.println("后序遍历的结果为"+"==============");
tree.reardisPlay(tree.root);
}
}
用数组来实现
package Binary.Tree;
public class BTreeArray {
//用数组实现二叉树的存储结构10 8 7 20 90 100 3 6 1 -10
int [] data;
public BTreeArray(int dat) {
int size=33;
data=new int[size];
data[1]=dat;
}
public BTreeArray(int size,int dat) {
data=new int[size];
data[1]=dat;
}
public void addNode(int dat) {
int i=1;
while(true) {
if(data[i]>dat) {//往下走
i=i*2;//左孩子下标
if(data[i]==0) {
data[i]=dat;
break;
}
}else {
i=i*2+1;
if(data[i]==0) {
data[i]=dat;
break;
}
}
}
}
public void disPlay() {
for(int i=1;i<data.length;i++) {
System.out.println("data["+i+"]"+"="+data[i]);
}
}
public static void main(String[] args) {
BTreeArray tree= new BTreeArray(10);
tree.addNode(8);
tree.addNode(7);
tree.addNode(20);
tree.addNode(90);
tree.addNode(100);
tree.addNode(3);
tree.addNode(6);
tree.addNode(1);
tree.addNode(-10);
tree.disPlay();
}
}