跟小刀学习 数据结构二叉树的实现

来源:互联网 发布:中国软件千股千评 编辑:程序博客网 时间:2024/04/30 14:37
  • 最近学习的有点累。导致二叉树学习的有点模糊
  • 我们之前学过数组 和链表 数组插入比较慢 链表查询比较慢。这时候我们就需要使用树这种结构。都比较快
  • 树的基本概念
  • :树最上面的节点称为根节点,一棵树只有一个根节点
  • 父节点:每一个节点都有一条边向上连接到另一个节点,这个节点就是称为下面这个节点的父节点
  • 子节点:每一个节点都有条向下连接的节点,下面的这个节点就是该节点的子节点
  • 叶子节点:没有子节点的节点也叫叶子节点.
  • 子树:每一个节点都可以作为一个子树的根。他和他的所有子节点组合在一起就是个子树
  • 查找节点:从根节点开始查找,如果查找的节点值比当前节点的值小,则继续查找左子树,否则查找右子树
  • 遍历树:遍历树是根据一个特定的顺序访问树的每一个节点,根据顺序的不同分为前序,中序,后序遍历三种。
  • 前序遍历。

    • (1)访问根节点
    • (2)前序遍历左子树
    • (3)前序遍历右子树
  • 中序遍历。

    • (1)中序遍历左子树
    • (2)访问根节点
    • (3)中序遍历右子树
  • 后序遍历。

    • (1)后序遍历左子树
    • (2)后序遍历右子树
    • (3)访问根节点

上代码:

/** * 二叉树的节点类 * @author Administrator * */public class Node {    public int iData;    public String sData;    public Node leftChild;    public Node rightChild;    public Node(int iData,String sData) {        this.iData = iData;        this.sData =sData;    }    public Node() {        // TODO Auto-generated constructor stub    }    public void dispalyNode(){        System.out.print("{"+ iData +"}");    }}

二叉树的具体实现

package com.chapter5_1;public class Tree {    //根节点    public Node root;    /**     * 二叉树的插入 s     */    public void insert(int d,String s){        //新节点        Node newNode = new Node(d,s);        //引用当前的节点        Node current = root;        //引用父节点        Node parent;        if(current == null){            root = newNode;            return ;//如果root节点为空的话,直接点添加都结束了        }          while(true){            //先将当前的节点付给一个parent. 这个节点一直在变动            parent = current;            if(d < current.iData){                //当前的节点变成刚才的左节点                current = current.leftChild;                if(current == null){                    parent.leftChild =newNode;                    return;                }            }else{//d > //              变成刚才的又节点                current = current.rightChild;                if(current == null){                    parent.rightChild= newNode;                    return;                }            }        }    }    /**     * 查找二叉树     * @param value     * @return     */    public Node find(int value){        Node current = root;        while(current.iData !=value){            //如果这个值比当前的节点值小,那么找左子节点            if(current.iData > value){                current = current.leftChild;            }else{                current = current.rightChild;            }            if(current == null){                return null;            }        }        return  current;    }    public void traverse(int traverseType){        switch (traverseType) {        case 1://            //前序遍历            System.out.println("前序遍历");            frontOrder(root);            break;        case 2:            System.out.println("中序遍历");            inOrder(root);            break;        case 3:            System.out.println("后序遍历");            postOrder(root);            break;        default:            break;        }        System.out.println("--------------------------------");    }    /**     * 前序遍历     * @param localNode     */    public void frontOrder(Node localNode){        if(localNode != null){            //访问根节点            System.out.println(localNode.iData +","+localNode.sData);            //前序遍历左子树            frontOrder(localNode.leftChild);            //前序遍历右子树            frontOrder(localNode.rightChild);        }    }    /**     *  中序遍历 -     * 1.中序遍历左子树     * 2.访问根节点     * 3.中序遍历右子树(从小到大)     * @param localNode     */    public void inOrder(Node localNode){        if(localNode != null){            //中序遍历左子树            inOrder(localNode.leftChild);            //访问根节点            System.out.println(localNode.iData +","+localNode.sData);            //中序遍历右子树            inOrder(localNode.rightChild);        }    }    /**     * 后序遍历。。先遍历左子树-右子树-访问根节点     * @param localNode     */    public void postOrder(Node localNode){        if(localNode != null){            //后序遍历左子树            postOrder(localNode.leftChild);            //后序遍历右子树            postOrder(localNode.rightChild);            //访问根节点            System.out.println(localNode.iData +","+localNode.sData);        }    }    /**     * 删除一个节点     * 有3种情况     * 1.该节点是叶子节点     * 2.该节点只有 一个节点     * 3.该节点有俩个节点。需要找到右边节点的最小节点。(中序遍历后继。。找到)     * @param value     * @return     */    public  boolean delete(int value){        //引用当前节点        Node current = root;        //引用父节点        Node parent = root;        //判断是否为左子节点        boolean isLeftChild  =true;        while(current.iData != value){            //先赋值            parent = current;            //如果这个值比当前的节点值小,那么找左子节点            if(current.iData > value){                current = current.leftChild;                isLeftChild  =true;            }else{                current = current.rightChild;                isLeftChild  =false;            }            if(current == null){                return false;            }        }        //删除叶子节点,也就是该节点没有子节点        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(current == root){//如果是根的话。就是根节点=当前的左子节点             root = current.leftChild;        }else if(isLeftChild){            parent.leftChild = current.leftChild;        }else{            parent.rightChild = current.leftChild;        }    }else if(current.leftChild == null){//只有一个节点  意思就是右子节点有数据        if(current == root) root = current.rightChild;        //这里看起来比较绕。。所以删除的时候可以自己画一个图。自己想        else if(isLeftChild){            parent.leftChild = current.rightChild;        }else{            parent.rightChild = current.rightChild;        }    }else{//有俩个节点。。。。        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;    }    public Node getSuccessor(Node delNode){        Node successor = delNode;        Node successorParent = delNode;        Node current =delNode.rightChild;        while(current != null){            successorParent =successor;            successor =current;//先右边然后然后一直找左子节点            current = current.leftChild;//一直往左子节点找        }        if(successor != delNode.rightChild){//这里没有看懂。            successorParent.leftChild = successor.rightChild;            successor.rightChild = delNode.rightChild;        }        return successor;    }}

测试代码:

package com.chapter5_1;public class Test {    public static void main(String[] args) {        Tree t = new Tree();        t.insert(10,"thinkpad");        t.insert(20,"mac");        t.insert(15,"del");        t.insert(3,"leishen");        t.insert(40,"zhangsan");        t.insert(16,"liao");        t.insert(4,"luyao");//      System.out.println(t.root.rightChild.iData);//      System.out.println(t.root.rightChild.leftChild.iData);//      System.out.println(t.root.leftChild.iData);//      Node node = t.find(15);////        System.out.println(node.iData +", " +  node.sData);//      node = t.find(3);////        System.out.println(node.iData +", " +  node.sData);        t.delete(3);//      t.traverse(1);        t.traverse(2);//      t.traverse(3);        t.delete(16);//      t.traverse(1);        t.traverse(2);    }}

至于测试结果我就不贴了。很多。在删除二叉树有俩个节点的时。我没有弄明白。我先贴代码。最近比较累。

0 0
原创粉丝点击