前言
再说二叉树遍历之前,先说一下二叉树的概念.二叉树是节点最多有两个子树的结构,他的子树一般称为左子树和右子树.二叉树的遍历 就是通过 或者中序遍历,或者前序遍历,或者后序遍历把二叉树的数据输出.官方的解释是从根节点出发,按照某种次序访问二叉树的所有节点,并使得每个节点被访问一次且仅访问一次
二叉树的性质
在二叉树第N层,至多有2的(i-1)次方个节点.比如下图中的第3层最多有4个节点
- 深度为N的二叉树,那么他至多有2的K次方-1个节点
- 对于任何一个二叉树,他的终端节点数等于度为2的节点数+1
- 具有n个节点的完全二叉树深度为log2N+1
- 如果有一个有N个节点的完全二叉树按照层序编号,对于任意一个节点I有
- I=1,他为二叉树的根,如果i>1,则双亲节点[i/2]
- 2i>n,则节点I没有左子树,否则左子树是节点2I
- 2I<+1> N,无右子树,否则右子树的节点为2I+1
二叉树的插入操作
二叉树的插入操作相对比较简单,就是判断要插入的节点是否要插入的位置左子树或者右子树为空即可
二叉树的删除操作
删除节点相对比较复杂,但也一般有三种情况
- 删除的是叶子节点,若是叶子节点,只要将其父节点指向空位置就行了
- 删除的是有一个子节点的节点,这种情况下,要删除的节点有两个链接,就是父节点和子节点,我们需要断开这个链接,然后,让其子节点和父节点相连即可
- 删除的节点有两个子节点,这种情况下,需要找到删除节点的中序后继,让中序后继替代要删除的节点的位置
二叉树的代码实现
package Linked;
import java.util.Stack;
/**
*
* @author Administrator
*/
public class TreeNode {
public static Node root;
public static boolean isEmaty(){
if(root==null){
return true;
}
return false;
}
public static Node getRoot(){
if(isEmaty()){
System.out.println("根节点为空");
return null;
}
return root;
}
//前序便利,根结点,做有
public static void oneDisplay(Node node){
//
// if(node!=null){
// System.out.print(node.data+" ");
// oneDisplay(node.leftChild);
// oneDisplay(node.rightChild);
// }
Node current=node;
Stack nodes=new Stack();
while(current!=null || nodes.size() > 0){
if(current!=null ){
System.out.print(current.data+" ");
nodes.push(current);
current=current.leftChild;
}else{
current=(Node) nodes.pop();
current=current.rightChild;
}
}
}
//查找结点
public static Node find(int data){
Node current=root;
while(current.data!=data){
if(current.data>data){
current=current.leftChild;
}else{
current=current.rightChild;
}
if(current==null){
System.out.println("无法找到结点");
return null;
}
}
System.out.println("找到结点"+current.data);
return current;
}
/**
* 该节点没有子节点
* 该节点有一个结点
* 该节点有两个节点
*/
public static void delect(int data){
Node curtent=root;
Node parent=curtent;
boolean isLeft=false;
while(curtent.data!=data){
parent=curtent;
if(curtent.data>data){
curtent=curtent.leftChild;
isLeft=true;
}else{
curtent=curtent.rightChild;
isLeft=false;
}
if(curtent==null){
System.out.println("找不到要删除的节点");
return;
}
}
//叶子节点
if(curtent.leftChild==null && curtent.rightChild==null){
System.out.println("你要删除的为叶子结点");
if(isLeft){
parent.leftChild=null;
}else{
parent.rightChild=null;
}
}else if(curtent.leftChild==null){
if(isLeft){
parent.leftChild=curtent.rightChild;
}else{
parent.rightChild=curtent.rightChild;
}
}else if(curtent.rightChild==null){
if(isLeft){
parent.leftChild=curtent.leftChild;
}else{
parent.rightChild=curtent.leftChild;
}
}else if(curtent.leftChild!=null && curtent.rightChild!=null){
Node newNode=curtent;
Node newNodeParent=newNode;
newNode=newNode.rightChild;
while(newNode.leftChild!=null){
newNodeParent=newNode;
newNode=newNode.leftChild;
}
if(newNode!=curtent.rightChild){
newNodeParent.leftChild=newNode.rightChild;
newNode.rightChild=curtent.rightChild;
}
if(isLeft){
parent.leftChild=newNode;
}else{
parent.rightChild=newNode;
}
newNode.leftChild=curtent.leftChild;
}
}
//插入一个结点
public static void insert(int data){
Node newNode=new Node(data);
if(isEmaty()){
root=newNode;
}else{
Node current=root;
Node parent;
while(true){
parent=current;
if(data<current.data){
current=current.leftChild;
if(current==null){
parent.leftChild=newNode;
return;
}
}else{
current=current.rightChild;
if(current==null){
parent.rightChild=newNode;
return;
}
}
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
insert(8);
insert(3);
insert(1);
insert(6);
insert(4);
insert(7);
insert(10);
insert(14);
insert(13);
delect(6);
delect(10);
oneDisplay(root);
}
public static class Node{
//双亲表示法,设一个结构指向自己的父母结点
// int data;
// Node parent;
//孩子表示法:一个数据域,多个指针域,每个指针域指向子树的根节点
//指针域的数量等于树的度,第二种指针域等于当前结点的度
// int data;
//
public Node(int data){
this.data=data;
}
int data;
Node leftChild;
Node rightChild;
}
}