一、概述
1.以二叉树为例熟悉树形结构,二叉树的定义如下:
1.1.二叉树:是结点有限的集合,这个集合或者是空,或者由一个根结点或两棵互不相交的称为左子树和右子树的二叉树组成。
二叉树是一个递归的定义,从中可以推导出另外两个定义,完全二叉树和满二叉树,分别如下:
1.2.满二叉树:2^k-1个结点的深度为K的二叉树。
1.3. 完全二叉树:树的结点对应于相同深度的满二叉树,可称为完全二叉树。
2.二叉树的基本操作:
建树/初始化:将树置空;
求根结点;
求父节点;
求孩子结点;
求兄弟子树;
插入子树;
删除子树;
遍历;
二、链式存储的二叉树的基本操作以及算法实现
因为顺序存储只适用于满二叉树,如果存储完全二叉树,会造成空间的大量浪费,比如最坏情况下,k度的完全二叉树每个节点只有左子树存在,这样将有2^k-k-1个节点存储空值。所以选用链表存储二叉树更合适。
树的链式存储结构可抽象出来,Java语言描述如下:
public class TreeNode{
int data;
TreeNode leftNode;
TreeNode rightNode;
public TreeNode(){
}
public TreeNode(int data){
this.data = data;
this.leftNode = null;
this.rightNode = null;
}
public TreeNode(int data,TreeNode leftNode,TreeNode rightNode){
this.data = data;
this.leftNode = leftNode;
this.rightNode = rightNode;
}
}
//实现二叉链表结构,建立二叉树
public TreeNode createTree(){
int data[] = {1,2,0,0,3,4,5,0,6,7,8,0,0,9};
TreeNode tree;
for(int i = 0; i<data.length; i++){
tree = new TreeNode(data[i]);
tree.leftNode = createTree();
tree.rightNode = createTree();
}
return tree;
}
2.1.二叉树的遍历操作
如果遵循先左后右的规则,那么二叉树的遍历方法可分为三种:先根序遍历;中根序遍历;后根序遍历。
//先根序的递归方法遍历
public void disp(TreeNode tree){
if(tree != null){
System.out.print(tree.data);
disp(tree.leftNode);
disp(tree.rightNode);
}
}
//中根序的递归方法遍历
public void disp(TreeNode tree){
if(tree != null){
disp(tree.leftNode);
System.out.print(tree.data);
disp(tree.rightNode);
}
}
//后根序的递归方法遍历
public void disp(TreeNode tree){
if(tree != null){
disp(tree.rightNode);
System.out.print(tree.data+" ");
disp(tree.leftNode);
}
}
这里可以借助栈的作用将此递归方法的遍历算法改为非递归方法,降低其时间复杂度,以先根序遍历算法为例,其基本思路为:从根结点走向左子树之前,将根结点的指针入栈保存,遍历完左子树之后,在将根结点指针出栈,得到根结点地址之后走向右结点,然后遍历右子树。
//建立栈用来保存根结点指针
public class Stack{
public final int MAXSIZE= 100;
public int elem[] ;
public int top;
public Stack(){
this.top = 0;
this.elem = new int[maxsize];
}
}
//遍历算法
public void disp(TreeNode tree){
Stack stack = new Stack();
final int MAXSIZE = stack.MAXSIZE;
do{
while(tree != null){
System.out.print(tree.data+" ");
if(stack.top==MAXSIZE){
System.out.print("stack is overflow");
return;
}
stack.push( tree);
tree = tree.leftNode;
}
if(stack.top != 0){
//取出跟指针并移向右子树
tree =stack.pop().rightNode;
}
}while(stack.top != 0|| tree != null);//栈非空或子树非空
}
点击查看更多内容
13人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦