二叉树数据Word格式文档下载.docx
- 文档编号:17654921
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:28
- 大小:38.02KB
二叉树数据Word格式文档下载.docx
《二叉树数据Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《二叉树数据Word格式文档下载.docx(28页珍藏版)》请在冰豆网上搜索。
n,则节点i没有孩子节点,否则其左孩子为2i。
若2i+1>
n,则节点i没有右孩子,否则其右孩子为2i+1。
∙若深度为k的二叉树有2^k-1个节点,则称其为满二叉树。
满二叉树是一棵完全二叉树。
∙对于完全二叉树中,度为1的节点个数只可能为1个或0个。
∙对于二叉树,如果叶子节点数为n0,度为1的节点数为n1,度为2的节点数为n2,则节点总数n=n0+n1+n2。
∙对于任意树,总节点数=每个节点度数和+1
∙二叉树的高度等于根与最远叶节点(具有最多祖先的节点)之间分支数目。
空树的高度是-1。
只有单个元素的二叉树,其高度为0。
.
三、二叉树的遍历
遍历是按某种策略访问树中的每个节点,且仅访问一次。
(一)二叉树结构实现
packagetree.bintree;
/**
*创建非完全二叉树、完全二叉树、满二叉树
*
*由于二叉树的节点增加没有什么规则,所以这里只是简单的使用了递一
*次性把整棵树创建出来,而没有设计出一个一个添加节点的方法与删除
*
*@authorjzj
*@date2009-12-23
*/
publicclassBinTree{//Bin=Binary(二进位的,二元的)
protectedEntryroot;
//根
privateintsize;
//树的节点数
/**
*树的节点结构
protectedstaticclassEntry{
intelem;
//数据域,这里我们作为编号
Entryleft;
//左子树
Entryright;
//右子树
publicEntry(intelem){
this.elem=elem;
}
publicStringtoString(){
return"
number="
+elem;
}
*根据给定的节点数创建一个完全二叉树或是满二叉树
*@paramnodeCount要创建节点总数
publicvoidcreateFullBiTree(intnodeCount){
root=recurCreateFullBiTree(1,nodeCount);
*递归创建完全二叉树
*@paramnum节点编号
*@paramnodeCount节点总数
*@returnTreeNode返回创建的节点
privateEntryrecurCreateFullBiTree(intnum,intnodeCount){
size++;
EntryrootNode=newEntry(num);
//根节点
//如果有左子树则创建左子树
if(num*2<
=nodeCount){
rootNode.left=recurCreateFullBiTree(num*2,nodeCount);
//如果还可以创建右子树,则创建
if(num*2+1<
rootNode.right=recurCreateFullBiTree(num*2+1,nodeCount);
}
return(Entry)rootNode;
*根据给定的数组创建一棵树,这个棵树可以是完全二叉树也可是普通二叉树
*数组中为0的表示不创建该位置上的节点
*@paramnums数组中指定了要创建的节点的编号,如果为0,表示不创建
publicvoidcreateBinTree(int[]nums){
root=recurCreateBinTree(nums,0);
*递归创建二叉树
*@paramindex需要使用数组中的哪个元素创建节点,如果为元素为0,则不创建
*@returnTreeNode返回创建的节点,最终会返回树的根节点
privateEntryrecurCreateBinTree(int[]nums,intindex){
//指定索引上的编号不为零上才需创建节点
if(nums[index]!
=0){
size++;
EntryrootNode=newEntry(nums[index]);
//如果有左子树则创建左子树
if((index+1)*2<
=nums.length){
rootNode.left=(Entry)recurCreateBinTree(nums,(index+1)*2-1);
//如果还可以创建右子树,则创建
if((index+1)*2+1<
rootNode.right=(Entry)recurCreateBinTree(nums,(index+1)*2);
}
return(Entry)rootNode;
returnnull;
publicintsize(){
returnsize;
//取树的最左边的节点
publicintgetLast(){
Entrye=root;
while(e.right!
=null){
e=e.right;
returne.elem;
//测试
publicstaticvoidmain(String[]args){
//创建一个满二叉树
BinTreebinTree=newBinTree();
binTree.createFullBiTree(15);
System.out.println(binTree.size());
//15
System.out.println(binTree.getLast());
//创建一个完全二叉树
binTree=newBinTree();
binTree.createFullBiTree(14);
//14
//7
//创建一棵非完全二叉树
int[]nums=newint[]{1,2,3,4,0,0,5,0,6,0,0,0,0,7,8};
binTree.createBinTree(nums);
//8
}&
nbsp;
(二)利用二叉树本身特点进行递归遍历(属内部遍历)
由于二叉树所具有的递归性质,一棵非空的二叉树可以看作是由根节点、左子树和右子树3部分构成,因为若能依次遍历这3部分的信息,也就遍历了整个二叉树。
按照左子树的遍历在右子树的遍历之前进行的约定,根据访问根节点位置的不同,可以得到二叉的前序、中序、后序3种遍历方法。
*二叉树的三种内部遍历:
前序、中序、后序
*但不管是哪种方式,左子树的遍历在右子树的遍历之前遍历是这有三种遍历方式都
*必须遵循的约定
publicclassBinTreeInOrderextendsBinTree{
*节点访问者,可根据需要重写visit方法
staticabstractclassVisitor{
voidvisit(Objectele){
System.out.print(ele+"
"
);
publicvoidpreOrder(Visitorv){
preOrder(v,root);
*树的前序递归遍历pre=prefix(前缀)
*@paramnode要遍历的节点
privatevoidpreOrder(Visitorv,Entrynode){
//如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null
if(node!
v.visit(node.elem);
//先遍历父节点
preOrder(v,node.left);
//再遍历左节点
preOrder(v,node.right);
//最后遍历右节点
publicvoidinOrder(Visitorv){
inOrder(v,root);
*树的中序递归遍历in=infix(中缀)
privatevoidinOrder(Visitorv,Entrynode){
inOrder(v,node.left);
//先遍历左节点
//再遍历父节点
inOrder(v,node.right);
publicvoidpostOrder(Visitorv){
postOrder(v,root);
*树的后序递归遍历post=postfix(后缀)
privatevoidpostOrder(Visitorv,Entrynode){
postOrder(v,node.left);
postOrder(v,node.right);
//再遍历右节点
//最后遍历父节点
//创建二叉树
BinTreeInOrdertreeOrder=newBinTreeInOrder();
treeOrder.createBinTree(nums);
System.out.print("
前序遍历-"
treeOrder.preOrder(newVisitor(){
});
System.out.println();
中序遍历-"
treeOrder.inOrder(newVisitor(){
后序遍历-"
treeOrder.postOrder(newVisitor(){
/*
*output:
*前序遍历-12463578
*中序遍历-46213758
*后序遍历-64278531
*/
(三)二叉树的非递归遍历(属外部遍历)
1、利用栈与队列对二叉树进行非递归遍历
importjava.util.Iterator;
importjava.util.LinkedList;
importjava.util.Stack;
*二叉树的外部遍历:
深度优先(先根)、广度(层次)优先遍历
publicclassBinTreeOutOrderextendsBinTree{
*二叉树深序优先遍历(即二叉树的先根遍历)迭代器,外部可以使用该迭代器
*进行非递归的遍历,这是一种在二叉树结构外部的一种遍历算法,它没有使用
*二叉树本身的结构特点(左右子树递归)进行递归遍历
privateclassDepthOrderIteratorimplementsIterator{
//栈里存放的是每个节点
privateStackstack=newStack();
publicDepthOrderIterator(Entrynode){
//根入栈,但在放入左右子节点前会马上出栈,即根先优于左右子节点访问
stack.push(node);
//是否还有下一个元素
publicbooleanhasNext(){
if(stack.isEmpty()){
returnfalse;
returntrue;
//取下一个元素
publicEntrynext(){
if(hasNext()){
//取栈顶元素
EntrytreeNode=(Entry)stack.pop();
//先访问根
if(treeNode.right!
stack.push(treeNode.right);
//再放入右子节点
if(treeNode.left!
stack.push(treeNode.left);
//最后放入左子节点,但访问先于右节点
//返回遍历得到的节点
returntreeNode;
}else{
//如果栈为空
returnnull;
publicvoidremove(){
thrownewUnsupportedOperationException();
*向外界提供先根遍历迭代器
*@returnIterator返回先根遍历迭代器
publicIteratorcreatePreOrderItr(){
returnnewDepthOrderIterator(root);
*二叉树广度优先遍历迭代器,外部可以使用该迭代器
privateclassLevelOrderIteratorimplementsIterator{
//使用队列结构实现层次遍历,队列里存储的为节点
privateLinkedListqueue=newLinkedList();
publicLevelOrderIterator(Entrynode){
if(node!
//将根入队
queue.addLast(node);
if(queue.isEmpty()){
//取栈顶迭元素
EntrytreeNode=(Entry)queue.removeFirst();
=null){//如果有左子树,加入有序列表中
queue.addLast(treeNode.left);
=null){//如果有右子树,加入有序列表中
queue.addLast(treeNode.right);
//如果队列为空
*向外界提供广度优先迭代器
*@returnIterator返回遍历迭代器
publicIteratorcreateLayerOrderItr(){
returnnewLevelOrderIterator(root);
//创建一棵满二叉树
BinTreeOutOrdertreeOrder=newBinTreeOutOrder();
treeOrder.createFullBiTree(15);
IteratorpreOrderItr=treeOrder.createPreOrderItr();
深度优先(先根)遍历-"
while(preOrderItr.hasNext()){
System.out.print(((Entry)preOrderItr.next()).elem+"
广度优先(层次)遍历-"
IteratorlayerOrderItr=treeOrder.createLayerOrderItr();
while(layerOrderItr.hasNext()){
System.out.print(((Entry)layerOrderItr.next()).elem+"
*深度优先(先根)遍历-124895101136121371415
*广度优先(层次)遍历-123456789101112131415
2、利用二叉树节点的父节点指针进行非递归遍历
要想采用非递归的方法遍历树,又不借助于前面的队列与栈,我们需要该树是一棵可回溯的二叉树,即从子节点要能够知道他的父节点及祖先节点,与前面的二叉树不同的是,树的节点结构体中多一个指向父的节点指针,这样外界可以以非递归的方式来遍历二叉树了。
*可回溯的二叉树
*二叉树的非递归遍历
publicclassBackBinTree{//Bin=Binary(二进位的,二元的)
privatestaticclassEntry{
//数据域,这里为了测试,就作为节点编号吧
Entryparaent;
//父节点
//左节点
//右节点
//构造函数只有两个参数,左右节点是调用add方法时设置
publicEntry(intelem,Entryparent){
this.paraent=parent;
*查找前序遍历(根左右)直接后继节点
*以非递归根左右的方式遍历树
*@parame需要查找哪个节点的直接后继节点
*@returnEntry前序遍历直接后继节点
publicEntrypreOrd
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉 数据
![提示](https://static.bdocx.com/images/bang_tan.gif)