二叉树
1.定义:每个结点至多只有两棵子树(二叉树的度不大于2),二叉树的子树有左右之分,其次序不能任意颠倒。
2.性质:
性质一:在二叉树的第i层至多有个2^(i-1)节点(i>=1)。
性质二:深度为k的二叉树至多有2^k-1个节点(k>=1)。(可求得4的定理)
性质三:对任何一个二叉树T,如果其叶子树为n0,度为2的结点数为n2,则n0=n2+1。
性质四:具有n个结点的完全二叉树的深度为(logn+1)向下取整。
性质五:如果对一棵有n个结点的完全二叉树编号,则对任一结点i(1<=i<=n),有(1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点i/2;(整数,注意在程序的/)。(2)如果2i>n,则结点i无左孩子(结点i为叶子节点);否则其左孩子是结点2i。(3)如果2i+1>n,则结点i无右孩子,否则其右孩子是结点2i+1。
3.补充
(1)一棵深度为k且有2^k-1个结点的二叉树称为满二叉树。
(2)对满二叉树连续编号,约定编号从根开始,自上至下,自左至右。深度为k的,有n个结点的二叉树,当其仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为完全二叉树。
4.二叉树的存储结构
(1)顺序存储结构
用一组地址连续的存储单元依次自上而下、自左至右存储完全二叉树上的结点元素,即将完全二叉树上编号为i的结点元素存储在如上定义的一维数组中下标为i-1的分量中。这种顺序存储结构仅适用于完全二叉树。
(2)链式存储结构
二叉树的结点由一个数据元素和分别指向其左右子树的两个分支构成.则表示二又树的链表中的结点至少包含3个域:数据域和左、右指针域。在含有理n个结点的二又链表中有n+1个空链域。
5.java代码的实现—二叉树的创建及遍历
package tree01;
/**
* 二叉树的创建以及三种遍历(前序,中序,后序)
* @author Administrator
*
*/
public class BinaryTreeTest {
public static void main(String[] args) {
BinaryTree bt=new BinaryTree();
System.out.println("前序遍历为:");
bt.preOrder();
System.out.println();
System.out.println("******************");
System.out.println("中序遍历为:");
bt.inOrder();
System.out.println();
System.out.println("******************");
System.out.println("后序遍历为:");
bt.postOrder();
}
}
//二叉树的创建
class BinaryTree{
//二叉树的根结点
private Node root;
//构造器
public BinaryTree() {
root=new Node("A");
createBinaryTree();
}
public void createBinaryTree() {
//手动生成结点对象
Node node2=new Node("B");
Node node3=new Node("C");
Node node4=new Node("D");
Node node5=new Node("E");
Node node6=new Node("F");
root.leftchild=node2;
root.rightchild=node3;
node2.leftchild=node4;
node2.rightchild=node5;
node3.leftchild=node6;
}
//前序遍历
public void preOrder() {
if(root!=null) {
root.preOrder();
}
else {
System.out.println("空");
}
}
//中序遍历
public void inOrder() {
if(root!=null) {
root.inOrder();
}
else {
System.out.println("空");
}
}
//后序遍历
public void postOrder() {
if(root!=null) {
root.postOrder();
}
else {
System.out.println("空");
}
}
}
//结点类
class Node{
//存储结点的数据
String data;
//结点左孩子的地址
Node leftchild;
//结点右孩子的地址
Node rightchild;
//构造器,每生成一个节点对象,传递一个值
public Node(String data) {
this.data = data;
}
//前序遍历----根->左->右(该方法为非静态方法,一旦调用,必是该类的对象调用)
public void preOrder() {
System.out.print(this.data+"->");
if(this.leftchild!=null) {
this.leftchild.preOrder();
}
if(this.rightchild!=null) {
this.rightchild.preOrder();
}
}
//中序遍历----左->根->右(该方法为非静态方法,一旦调用,必是该类的对象调用)
public void inOrder() {
if(this.leftchild!=null) {
this.leftchild.inOrder();
}
System.out.print(this.data+"->");
if(this.rightchild!=null) {
this.rightchild.inOrder();
}
}
//后序遍历----左->右->根(该方法为非静态方法,一旦调用,必是该类的对象调用)
public void postOrder() {
if(this.leftchild!=null) {
this.leftchild.postOrder();
}
if(this.rightchild!=null) {
this.rightchild.postOrder();
}
System.out.print(this.data+"->");
}
}
结果如下:
如有不足,望大家指教。