数据结构与算法之二叉树

树同时具有链表和数组的优点,关于树的术语有:
根:树顶端的节点
父节点:当前节点与之相连的上一层的节点
子节点:与当前节点直接相连的下一层节点的所有节点
叶子节点:没有子节点的节点
这里写一下相关代码:
树那个节点所对应的数据结构
//节点对象类,包含数据
public class Node {
   public int iData;//key value
   public double dData;
   public Node leftChild;//the Node's left child
   public Node rightChild;//the Node's right child
   public void displayNode(){
    System.out.print('{');
    System.out.print(iData);
       System.out.print(",");
       System.out.print(dData);
       System.out.print("}");
   }
}
//将数据插到树中
public void inser(int id,double dd){
    Node newNode=new Node();//创建一个新节点
    newNode.iData=id;
    newNode.dData=dd;
    if(root==null)
     root=newNode;
    else{
     Node current=root;
     Node parent;
     while(true){
      parent=current;
      if(id<current.iData){//查找左子树
       current=current.leftChild;
       if(current==null){
        parent.leftChild=newNode;
        return;
       }
      
      }else{
       current=current.rightChild;
       if(current==null){
        parent.rightChild=newNode;
        return;
       }
      }
     }
    }
   }
-----删除树的节点,这里需要考虑多种情况,第一种是要删除的节点下面没有任何子节点,第二种是只有左子树,第三种是只有右子树,第四种是左右两个子树都有
最后一种情况是最复杂的,当要删除节点的左右子树都有,我们需要从要删除节点的右子树中找到要一个最小的节点,因为二叉树中左边的节点值比同一级右边节点的值
大,所以我们只需要遍历要删除节点的左子树,找到最底层的左叶子节点,然后把该叶子节点的右子树给该叶子节点的父节点的左子节点,然后把该叶子节点的右子节点
指向要删除节点的右边子节点
下面是代码:
 }
   public boolean delete(int key) {//delete node with given key
    Node current=root;//assume the tree isn't empty
    Node parent=root;
    boolean isLeftChild=true;
    while(current.iData!=key){
     parent=current;
     if(key<current.iData){//查询左子树
      isLeftChild=true;
      current=current.leftChild;
     }else{
      isLeftChild=false;
      current=current.rightChild;
     }
     if(current==null){
      return false;
     }
    }
    //found node to delete
    //if there is no children,just delete it
    if(current.leftChild==null&&current.rightChild==null){
     if(current==root){
      root=null;
     }else if(isLeftChild){
      parent.leftChild=null;
     }else{
      parent.rightChild=null;
     }
    } else if(current.rightChild==null){//if no right child replace with left subtree
   if(current==root){
    root=null;
   }else if(isLeftChild){
    parent.leftChild=current.leftChild;
   }else{
    parent.rightChild=current.leftChild;
   }
    }else if(current.leftChild==null){//id no left child replace with right subtree
     if(current==root){
      root=null;
     }else if(isLeftChild){
      parent.leftChild=current.rightChild;
     }else{
      parent.rightChild=current.leftChild;
     }
    }else{//如果左节点和右节点都有
     //get  successor of node to delete
     Node successor=getSuccessor(current);
     if(current==root){
      root=successor;
     }else if(isLeftChild){
      parent.leftChild=successor;
     }else{
      parent.rightChild=successor;
     }
     successor.leftChild=current.leftChild;
    }
   
    return true;
   }
   //找后继节点
   private Node getSuccessor(Node deleteNode){
    Node successorParent=deleteNode;
    Node successor=deleteNode;
    Node current=deleteNode.rightChild;
    while(current!=null){
     successorParent=successor;
     successor=current;
     current=current.leftChild;
    }
    if(successor!=deleteNode.rightChild){
     successorParent.leftChild=successor.rightChild;
     successor.rightChild=deleteNode.rightChild;
    }
    /*
     * 当找到要替换的节点(该节点的左子节点是空的)以后,需要把该节点的右子节点给该节点的父节点的左子节点
     * 然后因为要剩下的节点所对应的数值都比这个要替换的节点大,所以要把要删除节点的右子节点给找到的节点的右子节点
    */
    return successor;
   }
  --接下来就是遍历,遍历有先序、后序、中序遍历可以通过递归直接遍历
 public void traverse(int traverseType){
    switch(traverseType){
    case 1: System.out.println("Preorder traversal:");
            preOrder(root);
            break;
    case 2: System.out.println("Inorder traversal");
            inOrder(root);
            break;
    case 3: System.out.println("postorder traversal");
            postOrder(root);
            break;
    }
   }
   //先序遍历
   private void preOrder(Node localRoot){
    if(localRoot!=null){
     System.out.println(localRoot.iData+ " ");
     preOrder(localRoot.leftChild);
     preOrder(localRoot.rightChild);
    }
   }
 //中序遍历
   private void inOrder(Node localRoot){
    if(localRoot!=null){
     inOrder(localRoot.leftChild);
     System.out.println(localRoot.iData+" ");
     inOrder(localRoot.rightChild);
    }
   }
   //后序遍历
   private void postOrder(Node localRoot){
    if(localRoot!=null){
     postOrder(localRoot.leftChild);
     postOrder(localRoot.rightChild);
     System.out.println(localRoot.iData+" ");
    }
   }
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Master_Yoda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值