java数据结构之三叉链表示的二叉树

三叉链表示的二叉树定义
所畏的三叉链表示是指二叉树由指向左孩子结点、右孩子结点、父亲结点【三叉】的引用(指针)数据和数据组成。
    package datastructure.tree.btree;  
    /**
     * 三叉链表示的二叉树定义
     * @author Administrator
     *
     */  
    public class BinTreeNode{  
        private Object data; // 数据域  
        private BinTreeNode parent; // 父节点  
        private BinTreeNode lChild; // 左孩子  
        private BinTreeNode rChild; // 右孩子  
        private int height; // 以该节点为根的子树的高度  
        private int size; // 该节点子孙数(包括结点本身)  
      
        public BinTreeNode() {  
            this(null);  
        }  
      
        public BinTreeNode(Object e) {  
            data = e;  
            height = 0;  
            size = 1;  
            parent = lChild = rChild = null;  
        }  
        //************ Node接口方法 *************/    
        /**
         *  获得结点的数据  
         */  
        public Object getData() {  
            return data;  
        }  
          
        public void setData(Object obj) {  
            data = obj;  
        }  
          
      
        //-------------辅助方法,判断当前结点位置的情况------------  
        /**
         * 判断是否有父亲
         * @return
         */  
        public boolean hasParent() {  
            return parent != null;  
        }  
          
        /**
         *  判断是否有左孩子
         * @return 如果有左孩子结点返回true,否则返回false
         */  
        public boolean hasLChild() {  
            return null != lChild;  
        }  
      
        /**
         *  判断是否有右孩子
         * @return
         */  
        public boolean hasRChild() {  
            return null != rChild;  
        }  
      
        /**
         *  判断是否为叶子结点
         * @return
         */  
        public boolean isLeaf() {  
            return (!hasLChild() && !hasRChild());  
        }  
      
        /**
         *  判断是否为某节点的左孩子
         * @return
         */  
        public boolean isLChild() {  
            return (hasParent() && this == parent.lChild);  
        }  
      
        /**
         *  判断是否为某结点的右孩子
         * @return
         */  
        public boolean isRChild() {  
            return (hasParent()) && this == parent.rChild;  
        }  
          
        //-------------- 与height相关的方法-----------------    
        /**
         * 取结点的高度,即以该节点为根的树的高度
         * @return
         */  
        public int getHeight() {  
            return height;  
        }  
          
        /**
         *  更新当前结点及其祖先的高度
         */  
        public void updateHeight() {  
            int newH = 0;// 新高度初始化为0,高度等于左右子树加1中的较大值  
            if (hasLChild())  
                newH = Math.max(newH, (lChild.getHeight() + 1));// //////////////???  
            if (hasRChild())  
                newH = Math.max(newH, (rChild.getHeight() + 1));// 先0和左孩子的高度加1进行比较,后左孩子高度加1和右孩子高度加1进行比较  
            if (newH == height)  
                return; // 高度没有发生变化则直接返回  
            height = newH; // 否则,更新高度  
            if (hasParent()) // 递归更新祖先的高度  
                parent.updateHeight();  
        }  
      
        /********* 与size相关的方法 **********/  
        /**
         *  取以该节点为根的树的结点数
         * @return
         */  
        public int getSize() {  
            return size;  
        }  
      
        /**
         *  更新当前结点及祖先的子孙数
         */  
        public void updateSize() {  
            size = 1; // 初始化为1,结点本身  
            if (hasLChild())  
                size = size + lChild.getSize(); // 加上左子树的规模  
            if (hasRChild())  
                size = size + rChild.getSize(); // 加上右子树的规模  
            if (hasParent())  
                parent.updateSize();  
        }  
      
        /********** 与parent相关的方法 **********/  
        /**
         *  取父节点
         * @return
         */  
        public BinTreeNode getParent() {  
            return parent;  
        }  
      
        /**
         *  断开与父亲的关系
         */  
        public void sever() {  
            if (!hasParent())  
                return;  
            if (isLChild())  
                parent.lChild = null;  
            else  
                parent.rChild = null;  
            parent.updateHeight(); // 更新父节点及其祖先的高度  
            parent.updateSize(); // 更新父节点及其祖先的规模  
            parent = null;  
        }  
      
        //********** 与lChild相关的方法 ********/  
        /**
         *  取左孩子
         * @return
         */  
        public BinTreeNode getLChild() {  
            return lChild;  
        }  
      
        /**
         *  设置当前结点的左孩子,返回原左孩子
         * @param lc
         * @return
         */  
        public BinTreeNode setLChild(BinTreeNode lc) {  
            BinTreeNode oldLC = this.lChild;  
            if (hasLChild()) {  
                lChild.sever();  
            } // 断开当前左孩子与结点的关系  
            if (null != lc) {  
                lc.sever(); // 判断lc与其父节点的关系  
                this.lChild = lc; // 确定父子关系  
                lc.parent = this;  
                this.updateHeight(); // 更新当前结点及其祖先的高度  
                this.updateSize(); // 更新当前结点及其祖先的规模  
            }  
            return oldLC; // 返回原左孩子  
        }  
      
        //********** 与rChild相关的方法 *********/  
        /**
         *  取右孩子
         * @return
         */  
        public BinTreeNode getRChild() {  
            return rChild;  
        }  
      
        /**
         *  设置当前结点为右孩子,返回原右孩子
         * @param rc
         * @return
         */  
        public BinTreeNode setRChild(BinTreeNode rc) {  
            BinTreeNode oldRC = this.rChild;  
            if (hasRChild()) {  
                rChild.sever();  
            } // 断开当前右孩子与结点的关系  
            if (null != rc) {  
                rc.sever(); // 断开rc与其父节点的关系  
                this.rChild = rc; // 确定父子关系  
                rc.parent = this;  
                this.updateHeight(); // 更新当前结点及其祖先的高度  
                this.updateSize(); // 更新当前结点及其祖先的规模  
            }  
            return oldRC; // 返回原右孩子  
        }  
        /**
         * 重写toString方法
         */  
        public String toString() {  
            return "" + data;  
        }  
      
    }

三叉链表示的二叉树的遍历
    package datastructure.tree.btree;  
    import java.util.*;  
    import datastructure.common.Strategy;  
    import datastructure.queue.Queue;  
    import datastructure.queue.ArrayQueue;  
    /**
     * 三叉链表示的二叉树的遍历
     * @author luoweifu
     *
     */  
    public class BinaryTreeOrder {  
        private int leafSize = 0;  
        private BinTreeNode root = null;  
        Strategy strategy = new StrategyEqual();  
          
        /**
         * 构造函数,传入树的根结点
         * @param node
         *            树的根结点
         */  
        public BinaryTreeOrder(BinTreeNode node) {  
            this.root = node;  
            Strategy strategy = new StrategyEqual();  
        }  
          
        public BinTreeNode getRoot() {  
            return root;  
        }  
      
        /**
         * 前序遍历
         *  
         * @return 返回一个Iterator容器
         */  
        public Iterator preOrder() {  
            List<BinTreeNode> list = new LinkedList();  
            preOrderRecursion(this.root, list);  
            return list.iterator();  
        }  
      
        /**
         * 递归定义前序遍历
         * @param rt
         *            树根结点
         * @param list
         *            LinkedList容器
         */  
        private void preOrderRecursion(BinTreeNode rt, List list) {  
            if (null == rt)  
                return; // 递归基,空树直接返回  
            list.add(rt); // 访问根节点  
            preOrderRecursion(rt.getLChild(), list);// 遍历左子树  
            preOrderRecursion(rt.getRChild(), list);// 遍历右子树  
        }  
      
        /**
         * 中序遍历
         *  
         * @return
         */  
        public Iterator inOrder() {  
            List<BinTreeNode> list = new LinkedList();  
            inOrderRecursion(this.root, list);  
            return list.iterator();  
        }  
      
        /**
         * 递归定义中序遍历
         * @param rt
         *            树根结点
         * @param list
         *            LinkedList容器
         */  
        private void inOrderRecursion(BinTreeNode rt, List list) {  
            if (null == rt)  
                return; // 递归基,空树直接返回  
            inOrderRecursion(rt.getLChild(), list);// 遍历左子树  
            list.add(rt); // 访问根节点  
            inOrderRecursion(rt.getRChild(), list);// 遍历右子树  
        }  
      
        /**
         *  后序遍历
         * @return
         */  
        public Iterator postOrder() {  
            List<BinTreeNode> list = new LinkedList();  
            postOrderRecursion(this.root, list);  
            return list.iterator();  
        }  
          
        /**
         * 递归定义后序遍历
         * @param rt
         *            树根结点
         * @param list
         *            LinkedList容器
         */  
        private void postOrderRecursion(BinTreeNode rt, List list) {  
            if (null == rt)  
                return; // 递归基,空树直接返回  
            postOrderRecursion(rt.getLChild(), list);// 遍历左子树  
            postOrderRecursion(rt.getRChild(), list);// 遍历右子树  
            list.add(rt);// 访问根节点  
        }  
      
        /**
         *  按层遍历
         * @return
         */  
        public Iterator levelOrder() {  
            List<BinTreeNode> list = new LinkedList();  
            levelOrderTraverse(this.root, list);  
            return list.iterator();  
        }  
      
        /**
         *  使用队列完成二叉树的按层遍历
         * @param rt
         * @param list
         */  
        private void levelOrderTraverse(BinTreeNode rt, List list) {  
            if (null == rt)  
                return;  
            Queue q = new ArrayQueue();  
            q.push(rt);// 根节点入队列  
            while (!q.isEmpty()) {  
                BinTreeNode p = (BinTreeNode) q.deQueue(); // 取出队首节点p并访问  
                list.add(p);  
                if (p.hasLChild())  
                    q.push(p.getLChild()); // 将p的非空左右孩子依次入队列  
                if (p.hasRChild())  
                    q.push(p.getRChild());  
            }  
        }  
      
        /**
         *  在树中查找元素e,并返回其所在的结点
        * @param e 要查找的数据元素
         * @return 返回找到的结点
         */  
        public BinTreeNode find(Object e) {  
            return searchE(root, e);  
        }  
      
        /**
         * 递归查找元素e
         * @param rt 树的根
         * @param e 要查找的数据元素
         * @return 返回找到的结点
         */  
        private BinTreeNode searchE(BinTreeNode rt, Object e) {  
            if (null == rt)  
                return null;  
            if (strategy.equal(rt.getData(), e))  
                return rt;  
            BinTreeNode v = searchE(rt.getLChild(), e);  
            if (null == v)  
                v = searchE(rt.getRChild(), e);  
            return v;  
        }  
        /**
         * 打印二叉树
         * @return
         */  
        public String printBinTree() {  
            StringBuilder sb = new StringBuilder();  
            printBinTree(root, 0, sb);  
            return sb.toString();  
        }  
      
        /**
         * 打印二叉树
         * @param btree 根结点
         * @param n 结点层数
         * @param sb 用于保存记录的字符串
         */  
        private void printBinTree(BinTreeNode btree, int n, StringBuilder sb) {  
            if (null == btree)  
                return;  
            printBinTree(btree.getRChild(), n + 1, sb);  
            for (int i = 0; i < n; i++)  
                sb.append("\t");  
            if (n >= 0)  
                sb.append(btree.getData() + "\n");  
            printBinTree(btree.getLChild(), n + 1, sb);  
        }  
      
         /**
          * 求叶结点的个数
          * @return 叶结点的个数
          */  
        public int sizeLeaf() {  
            searchLeaf(this.root);  
            return leafSize;  
        }  
        /**
         * 叶结点的个数
         * @param rt
         */  
        private void searchLeaf(BinTreeNode rt) {  
            if (null == rt)  
                return;  
            if (rt.isLeaf())  
                leafSize++;  
            else {  
                searchLeaf(rt.getLChild());  
                searchLeaf(rt.getRChild());  
            }  
        }  
      
    }

测试
    package datastructure.tree.btree;   
    import java.util.Iterator;  
      
    public class BTreeTest2 {  
        // 测试功能  
        // 结果:所有功能都能实现,正确  
        public static void main(String args[]) {  
            //构造二叉树  
            BinTreeNode roots = new BinTreeNode();  
            BinTreeNode node = new BinTreeNode();  
            roots.setData(‘A‘);  
            roots.setLChild(new BinTreeNode(‘B‘));  
            roots.setRChild(new BinTreeNode(‘C‘));  
            node = roots.getLChild();  
            node.setLChild(new BinTreeNode(‘D‘));  
            node.setRChild(new BinTreeNode(‘E‘));  
            node = roots.getRChild();  
            node.setLChild(new BinTreeNode(‘F‘));  
            BinaryTreeOrder order = new BinaryTreeOrder(roots);  
            //------遍历--------  
            Iterator<BinTreeNode> iter1 = order.preOrder();  
            System.out.println("前序遍历:");  
            printIterator(iter1);  
              
            Iterator<BinTreeNode> iter2 = order.inOrder();  
            System.out.println("中序遍历:");  
            printIterator(iter2);  
              
            Iterator<BinTreeNode> iter3 = order.postOrder();  
            System.out.println("后序遍历:");  
            printIterator(iter3);  
              
            Iterator<BinTreeNode> iter4 = order.levelOrder();  
            System.out.println("层次遍历:");  
            printIterator(iter4);  
                      
            String str = order.printBinTree();  
            System.out.println("打印二叉树:\n" + str);  
            System.out.println("叶结点的个数:" + order.sizeLeaf());   
            BinTreeNode nodeone = order.find(‘E‘);   
            System.out.println("根结点的数据元素:" + nodeone.getData());  
        }  
        public static void printIterator(Iterator<BinTreeNode> iter) {  
            while(iter.hasNext()) {  
                System.out.print("\t" + iter.next().getData());  
            }  
            System.out.println();  
        }  
          
    }

结果:
前序遍历:
A BD
E C F
中序遍历:
D BE
A F C
后序遍历:
D EB
F C A
层次遍历:
A BC
D E F
打印二叉树:
C
F
A
E
B
D

叶结点的个数:3
根结点的数据元素:E

转载至:http://blog.csdn.net/luoweifu/article/details/9089551

时间: 2024-08-29 23:18:48

java数据结构之三叉链表示的二叉树的相关文章

java数据结构:单链表常见操作代码实现

一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashMap等集合的底层结构都是链表结构.链表以结点作为存储单元,这些存储单元可以是不连续的.每个结点由两部分组成:存储的数值+前序结点和后序结点的指针.即有前序结点的指针又有后序结点的指针的链表称为双向链表,只包含后续指针的链表为单链表,本文总结的均为单链表的操作. 单链表结构: Java中单链表采用No

I学霸官方免费教程三十七:Java数据结构之单向链表结构

数据结构之单向链表 例如:现有双向链表OneWayLinked中存储着1,2,3,4四个元素,那么集合对象中会有4个节点A.B.C.D,由上述结构可以知道,节点A中存储着元素1和节点B:节点B中存储着元素2和节点C,节点C中存储着元素3和节点D,节点D中存储着元素4和null.如果现在要在元素2和3中间插入一个元素5:过程如下:1.创建节点E,E中存储元素52.将B中的下一个节点修改为节点E3.将E中的下一个节点赋值为节点C从上述过程看,插入时没有节点位置移动的操作,所以效率比较高:删除的过程和

Java数据结构之单链表

链表的组成:链表头+结点 ? ?链表头一般只存储下一个节点的引用 ? ?节点:存数据+下一个节点的引用 链表头代码: package?com.xingej.algorithm.datastructure.linkedList.singleLinkedList; /** ?*?声明一个链表的头部 ?*? ?*?从链表头的使用,联想到hadoop,spark,netty中都有上下文context ?*? ?*[email protected]?erjun?2017年12月8日?上午8:45:08 ?

二叉树的三叉链表存储及其Java实现

三叉链表存储的思想是让每个节点持有三个引用parent.left.right,分别指向其父节点.左子节点和右子节点.如下图所示: 因此,三叉链表存储的节点大致如: class Node{ T data; Node parent; Node left; Node right; } Java实现代码: package com.liuhao.DataStructures; import com.liuhao.DataStructures.TwoLinkBinTree.TreeNode; public

java数据结构与算法之树基本概念及二叉树(BinaryTree)的设计与实现

[版权申明]未经博主同意,不允许转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53727333 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) java数据结构与算法之栈(Stack)设

java数据结构与算法之顺序表与链表深入分析

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 ??数据结构与算法这门学科虽然在大学期间就已学习过了,但是到现在确实也忘了不少,因此最近又重新看了本书-<数据结构与算法分析>加上之前看的<java数据结构>也算是对数据结构的进一步深入学习了,于是也就打算

数据结构Java实现04----循环链表、仿真链表

数据结构Java实现04----循环链表.仿真链表 单向循环链表 双向循环链表 仿真链表 一.单向循环链表: 1.概念: 单向循环链表是单链表的另一种形式,其结构特点是链表中最后一个结点的指针不再是结束标记,而是指向整个链表的第一个结点,从而使单链表形成一个环. 和单链表相比,循环单链表的长处是从链尾到链头比较方便.当要处理的数据元素序列具有环型结构特点时,适合于采用循环单链表. 和单链表相同,循环单链表也有带头结点结构和不带头结点结构两种,带头结点的循环单链表实现插入和删除操作时,算法实现较为

Java数据结构-二叉树及其遍历

二叉树的定义:n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互相不相交的.分别称为根结点的左子树和右子树的二叉树组成. 二叉树的特点: 0<=度<=2: 左右子树是有顺序的,不能颠倒: 不论有几棵子树,也要区分它是左子树还是右子树. 二叉树的五种基本形态: 空二叉树: 只有一个根结点: 根结点只有左子树: 根结点只有右子树: 根结点既有左子树又有右子树. 举例3个结点的二叉树的形态有: 下面说一些特殊的二叉树. 斜树:所有的结点都只有左子树的二叉

java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制)

转载请注明出处(请尊重原创!谢谢~): http://blog.csdn.net/javazejian/article/details/53073995 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) ??这篇是数据结构与算法的第3篇,通过前两篇的介绍,对应顺序表和链表已有