二叉树的简单实现

二叉树

概念:树(tree)是由n(n>=0)个结点组成的有限集合(树中元素通常称为结点)。n=0的树称为空树,n>0的树T由以下两个条件约定构成:

  • 有一个特殊结点称为根(root)结点,他只有后继结点,没有前驱结点

  • 除根结点外的其他结点分为m个互不相交的集合Tn…其中每个集合Ti也具有树结构,称为根的子树(Subtree)

    下列代码中对于二叉树的非递归遍历和层次遍历分别用到栈和队列

    //栈的实现
    public class LinkedStack<T>implements stackInterface<T> {
        class Node{
            T data;
            Node pre;
            Node(T t){
                this.data = t;
            }
            @Override
            public String toString() {
                return "["+this.data+"]";
            }
        }
        //作为指针,指向栈顶元素
        Node root,pointer;
        public LinkedStack(){
            root =new Node(null);
            pointer = root;
        }
        @Override
        public Object Pop() {
            if (root.pre==null){
                throw new IndexOutOfBoundsException("stack overflow");
            }
            Object temp = pointer;
            pointer = pointer.pre;
            return temp;
        }
    
        @Override
        public void Push(T t) {
            if(root.pre==null){
                Node newNode = new Node(t);
                root.pre =newNode;
                pointer = newNode;
            }
            Node newNode = new Node(t);
            newNode.pre = pointer;
            pointer = newNode;
        }
    
        @Override
        public Object Peek() {
            if (root.pre==null){
                throw new IndexOutOfBoundsException("stack overflow");
            }
            return pointer;
        }
    
        @Override
        public boolean IsEmpty() {
            return root.pre==null;
        }
        //通过递归获取倒数第二个结点
    
    }
    
    //树结点的实现
    public class BinaryNode<T>{
        T data;//数据
        BinaryNode<T> left,right;//左 右孩子结点
        public BinaryNode(T data,BinaryNode<T> left,BinaryNode<T> right){//构造结点
            this.data= data;
            this.left = left;
            this.right = right;
        }
    
        public BinaryNode(T data){//构造叶子节点
            this(data,null,null);
    
        }
        public String toString(){//返回数据域的字符串描述
            return this.data.toString();
        }
        public boolean isLeaf(){//判断当前结点是否为叶子节点
            return this.left==null&&this.right==null;
        }
    }
    
    
    //队列的实现
    package day03.queue.LinkedQueue;
    import day03.queue.queueInterface.queue;
    /**
     * @author:sncot
     * @date:7:59 2022/7/27
     */
    public class LinkedQueue<T> implements queue<T> {
        class Node{
            T data;
            Node pre;
            Node (T t){
                this.data = t;
            }
            @Override
            public String toString() {
                return "["+this.data+"]";
            }
        }
        int num;
        Node rear,front;
        @Override
        public void Add(T t) {
            if (num==0){
                Node newNode = new Node(t);
                rear = front=newNode;
                num++;
                return;
            }
            Node newNode = new Node(t);
            rear.pre= newNode;
            num++;
        }
        @Override
        public Object Poll() {
            if (num==0){
                System.out.println("queue is empty");
                return null;
            }
            Object temp = front;
            front = front.pre;
            num--;
            return temp;
        }
        @Override
        public Object Peek() {
            if(num==0){
                System.out.println("queue is null");
                return null;
            }
            return front;
        }
        @Override
        public boolean IsEmpty() {
            return num==0;
        }
    }
    
    
    //树的相关操作方法的实现
    package day04.tree.binaryTree;
    import day03.queue.LinkedQueue.LinkedQueue;
    import day03.stack.linkedStack.LinkedStack;
    /**
     * @author:sncot
     * @date:10:27 2022/8/1
     */
    public class BinaryTree <T>{
        BinaryNode<T> root;//根节点
    
        public BinaryNode<T> insert(T t){//插入x作为根节点,原根节点作为x的左孩子结点,返回插入节点
            return this.root = new BinaryNode<>(t,this.root,null);
        }
        //插入结点为指定节点parent的左/右孩子结点
        public BinaryNode<T> insert(BinaryNode<T> parent,T t,boolean leftChild){
            if (t == null) {
                return null;
            }
            if(leftChild){
                return parent.left = new BinaryNode<>(t,parent.left,null);
            }else{
                return parent.right = new BinaryNode<>(t,null,parent.right);
            }
        }
        //删除指定节点parent的左/右子树
        public void remove(BinaryNode<T> parent,boolean leftChild){
            if (leftChild){
                parent.left=null;
            }else{
                parent.right=null;
            }
        }
        //删除二叉树的所有结点
        public void clear(){
            this.root = null;
        }
        //二叉树的先根次序遍历
        public void preOrder(){//递归遍历
            preOrder(this.root);
        }
        private void preOrder(BinaryNode<T> node){
            if (node!=null){
                System.out.println(node.data.toString()+"");
                preOrder(node.left);
                preOrder(node.right);
            }
        }
    
        //非递归 借助栈实现先根次序遍历
        public void PreOrderTraverse(){//非递归
            System.out.println("先根遍历 非递归:");
            LinkedStack<BinaryNode<T>> stack = new LinkedStack<>();
            BinaryNode<T> p = this.root;
            while(p!=null|| !stack.IsEmpty()){//当栈非空或者当前结点不为空时
                if(p!=null){
                    System.out.println(p.data+"");
                    stack.Push(p);
                    p=p.left;//进入左子树
                }else{//p为空栈非空时
                    System.out.println("null");
                    p = (BinaryNode<T>) stack.Pop();//p指向出栈结点
                    p = p.right;//进入右子树
                }
                System.out.println();
            }
        }
        public void postOrder(){
            postOrder(this.root);
        }
        private void postOrder(BinaryNode<T> node){
            if(node!=null){
                postOrder(node.left);
                postOrder(node.right);
                System.out.println(node.data.toString()+"");
            }
        }
        public void inOrder(){
            inOrder(this.root);
        }
        private void inOrder(BinaryNode<T> node){
            if (node!=null){
                inOrder(node.left);
                System.out.println(node.data.toString()+"");
                inOrder(node.right);
            }
        }
        //借助队列实现层次遍历二叉树
        public void levelOrder(){
            System.out.println("层次遍历二叉树:");
            LinkedQueue<BinaryNode<T>> queue = new LinkedQueue<>();//创建一个空队列
            BinaryNode<T> p = this.root;//根节点没有入队
            while(p!=null){
                System.out.println(p.data+"");//访问p结点
                if (p.left!=null){
                    queue.Add(p.left);
                }
                if (p.right!=null){
                    queue.Add(p.right);
                }
                p = (BinaryNode<T>) queue.Poll();//p指向出队结点,若队列为空返回null
            }
            System.out.println();
        }
    }
    
    public class main {
        public static void main(String[] args) {
            BinaryTree<String> tree = new BinaryTree<>();
            tree.insert("A");
            tree.insert("B");
            tree.insert("C");
            tree.insert("D");
            tree.insert("E");
            tree.insert("F");
            tree.insert("G");
            tree.postOrder();
            System.out.println("--------------------");
            tree.preOrder();
            System.out.println("==========================");
            tree.inOrder();
            tree.PreOrderTraverse();
            System.out.println("===++++++++++++++++++");
            tree.levelOrder();
    
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值