• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

dream311

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

九、二叉树

树通常结合了另外两种数据结构的优点:一种是有序数组,另一种是链表。在树中查找数据项的速度和在有序数组中查找一样快,并且插入数据项和删除数据项的速度也和链表一样。

1、二叉搜索树:一个节点的左子节点的关键字值小于这个节点,右子节点的关键字值大于或等于这个父节点。

// to run this program: C>java TreeApp
import java.io.*;
import java.util.*;          
class TreeNode
{
   public int data;               
   public TreeNode leftChild;       
   public TreeNode rightChild;
   public TreeNode parent;  
 
   public TreeNode(int data,TreeNode leftChild
                   ,TreeNode rightChild,TreeNode parent)
   {
      this.data = data;
      this.leftChild = leftChild;
      this.rightChild = rightChild;
      this.parent = parent;
   }    

   public int getData()     
   {
      return this.data;
   }
} 

class BinarySearchTree
{
   private TreeNode root;       

   public BinarySearchTree()               
   {  root = null;  }   

   public TreeNode getRoot()
   {  return this.root;  }

//判断二叉查找树是否为空;
  public boolean isEmpty()
  {
     if(root==null)
        return true;
     else
        return false;
  }       

   //在二叉查找树中查询给定关键字
   public TreeNode find(int key) 
   {                           
      TreeNode currentNode = root;         
      while(currentNode!=null && currentNode.data!=key)
      {
         if(key < currentNode.data)
            currentNode = currentNode.leftChild;
          else 
            currentNode = currentNode.rightChild;
      } 
      return currentNode;            
   } 
  
   //查找二叉查找树中的最小关键字节点
   public TreeNode minNode(TreeNode node)
   {
       if(node ==null)
          return null;
       TreeNode currentNode = node;
       while(currentNode.leftChild!=null)
          currentNode = currentNode.leftChild;
       return currentNode;
   }

   //查找二叉查找树中的最大关键字节点
   public TreeNode maxNode(TreeNode node)
   {
      if(node ==null)
         return null;
      TreeNode currentNode = node;
      while(currentNode.rightChild!=null)
         currentNode = currentNode.rightChild;
      return currentNode;
   }
 
   //前序遍历
   public void preOrder(TreeNode node)
   {
      if(node != null)
      {
         System.out.print(node.data + " ");
         preOrder(node.leftChild);
         preOrder(node.rightChild);
      }
   }

   //中序遍历
   public  void inOrder(TreeNode node)
   {
      if(node != null)
      {
         inOrder(node.leftChild);
         System.out.print(node.data + " ");
         inOrder(node.rightChild);
      }
   }

   //中序遍历,每个节点显示前驱和后继节点
   public  void testNode(TreeNode node)
   {
      if(node != null)
      {
         testNode(node.leftChild);
         TreeNode node1 = getPrecessor(node);
         TreeNode node2 = getSuccessor(node);
         System.out.print("本节点:"+node.getData());
         if(node1 != null)
            System.out.print("    前驱节点:"+node1.getData());
         else
            System.out.print("    没有前驱节点");
         if(node2 != null)
            System.out.print("    后继节点:"+node2.getData());
         else
            System.out.print("    没有后继节点");
        System.out.println("");
        testNode(node.rightChild);
      }
   }

   //后序遍历
   public  void postOrder(TreeNode node)
   {
      if(node != null)
      {
         postOrder(node.leftChild);
         postOrder(node.rightChild);
         System.out.print(node.data + " ");
      }
   }

   //插入节点
   public void insert(int key)
   {
      TreeNode newNode = new TreeNode(key,null,null,null); 
      if(root == null)
      {
         root = newNode;
         return;
      }           
      TreeNode currentNode = root;
      TreeNode parentNode = null;
      while(currentNode != null)
      {
         parentNode = currentNode;
         if(key < currentNode.data)
            currentNode = currentNode.leftChild;
         else if(key > currentNode.data)
            currentNode = currentNode.rightChild;
         else
         //树中已存在匹配给定关键字的节点,则什么都不做直接返回
            return;
      }
    //parentNode就是最后一个非空的节点
      if(key < parentNode.data)
      {
         parentNode.leftChild = newNode;
         newNode.parent = parentNode;
      }
      else
      {
         parentNode.rightChild = newNode;
         newNode.parent = parentNode;
      }
   }   

   //删除节点
   public boolean delete(TreeNode node)
   {          
      TreeNode currentNode = node;
      if(currentNode == null)
         return false;
   
//key节点没有孩子 if(currentNode.leftChild == null && currentNode.rightChild == null) { //key节点是根节点 if(currentNode == root) { root = null; return true; } //key节点是其父节点的左孩子 TreeNode parentNode = currentNode.parent; if(currentNode ==parentNode.leftChild) parentNode.leftChild = null; //key节点是其父节点的右孩子 else parentNode.rightChild = null; return true; } //key节点只有左孩子 if(currentNode.leftChild != null && currentNode.rightChild == null) { //key节点是根节点 if(currentNode == root) { root = currentNode.leftChild; root.parent=null; return true; } //key节点是其父节点的左孩子 TreeNode parentNode = currentNode.parent; if(currentNode == parentNode.leftChild) { parentNode.leftChild = currentNode.leftChild; currentNode.leftChild.parent = parentNode; } //key节点是其父节点的右孩子 else { parentNode.rightChild = currentNode.leftChild; currentNode.leftChild.parent = parentNode; } return true; } //key节点只有右孩子 if(currentNode.leftChild == null && currentNode.rightChild != null) { //key节点是根节点 if(currentNode == root) { root = currentNode.rightChild; root.parent = null; return true; } //key节点是其父节点的左孩子 TreeNode parentNode = currentNode.parent; if(currentNode == currentNode.parent.leftChild) { parentNode.leftChild = currentNode.rightChild; currentNode.rightChild.parent = parentNode; } //key节点是其父节点的右孩子 else { parentNode.rightChild = currentNode.rightChild; currentNode.rightChild.parent = parentNode; } return true; } //key节点左右孩子都有 if(currentNode.leftChild != null && currentNode.rightChild != null) { TreeNode successorNode = getSuccessor(currentNode); delete(successorNode); currentNode.data = successorNode.data; } return true; } //查找给定节点在中序遍历下的后继节点 private TreeNode getSuccessor(TreeNode node) { //子树为空 if(node == null) return null; //若该节点的右子树不为空,则其后继节点就是右子树中的最小关键字节点 if(node.rightChild!=null) return minNode(node.rightChild); //若该节点右子树为空,则向上一直找它的祖先,直到一个祖先是另一个祖先的左孩子 TreeNode parentNode = node.parent; while(parentNode!=null && node==parentNode.rightChild) { node = parentNode; parentNode = parentNode.parent; } return parentNode; } //查找给定节点在中序遍历下的前驱节点 public TreeNode getPrecessor(TreeNode node) { //子树为空 if(node == null) return null; //若该节点的左子树不为空,则其后继节点就是右子树中的最大关键字节点 if(node.leftChild!=null) return maxNode(node.leftChild); //若该节点左子树为空,则向上一直找它的祖先,直到一个祖先是另一个祖先的右孩子 TreeNode parentNode = node.parent; while(parentNode!=null && node == parentNode.leftChild) { node = parentNode; parentNode = parentNode.parent; } return parentNode; } } class BinarySearchTreeApp { public static void main(String[] args) throws IOException { BinarySearchTree bst = new BinarySearchTree(); System.out.print("二叉查找树是否为空?"); if(bst.isEmpty()==true) System.out.println("是"); else System.out.println("否"); int[] keys = new int[] { 15, 6, 18, 3, 7, 13, 20, 2, 9, 4 }; // int[] keys = new int[] { }; for(int key : keys) bst.insert(key); System.out.print("二叉查找树是否为空?"); if(bst.isEmpty()==true) System.out.println("是"); else System.out.println("否"); System.out.print("根节点关键字: " ); if(bst.getRoot()!=null) System.out.println(bst.getRoot().getData());
System.out.print(
"最小关键字: "); if(bst.getRoot()!=null) System.out.println( bst.minNode(bst.getRoot()).getData()); System.out.print("最大关键字: "); if(bst.getRoot()!=null) System.out.println( + bst.maxNode(bst.getRoot()).getData()); System.out.print("前序遍历: " ); bst.preOrder(bst.getRoot()); System.out.println(""); System.out.print("中序遍历: " ); bst.inOrder(bst.getRoot()); System.out.println(""); System.out.print("后序遍历: " ); bst.postOrder(bst.getRoot()); System.out.println(""); bst.testNode(bst.getRoot()); //删除13这个节点 TreeNode node = bst.find(13); bst.delete(node); node = null; System.out.println(""); System.out.print("中序遍历: " ); bst.inOrder(bst.getRoot()); System.out.println(""
); bst.testNode(bst.getRoot()); }
}

 

二叉查找树是否为空?是
二叉查找树是否为空?否
根节点关键字: 15
最小关键字: 2
最大关键字: 20
前序遍历: 15 6 3 2 4 7 13 9 18 20 
中序遍历: 2 3 4 6 7 9 13 15 18 20 
后序遍历: 2 4 3 9 13 7 6 20 18 15 
本节点:2    没有前驱节点    后继节点:3
本节点:3    前驱节点:2    后继节点:4
本节点:4    前驱节点:3    后继节点:6
本节点:6    前驱节点:4    后继节点:7
本节点:7    前驱节点:6    后继节点:9
本节点:9    前驱节点:7    后继节点:13
本节点:13    前驱节点:9    后继节点:15
本节点:15    前驱节点:13    后继节点:18
本节点:18    前驱节点:15    后继节点:20
本节点:20    前驱节点:18    没有后继节点

中序遍历: 2 3 4 6 7 9 15 18 20 
本节点:2    没有前驱节点    后继节点:3
本节点:3    前驱节点:2    后继节点:4
本节点:4    前驱节点:3    后继节点:6
本节点:6    前驱节点:4    后继节点:7
本节点:7    前驱节点:6    后继节点:9
本节点:9    前驱节点:7    后继节点:15
本节点:15    前驱节点:9    后继节点:18
本节点:18    前驱节点:15    后继节点:20
本节点:20    前驱节点:18    没有后继节点

 

posted on 2015-11-25 21:17  dream311  阅读(148)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3