数据结构上机作业(四)

这篇博客详细介绍了二叉树的基本概念和二叉链表存储结构,通过递归和非递归方式实现了二叉树的前序、中序、后序遍历以及层次遍历算法。此外,还提供了计算二叉树深度和叶子节点数量的方法,是理解数据结构中二叉树操作的实用教程。

一.上机内容

1、熟悉二叉树基本概念和存储结构,在实现二叉树的二叉链表存储结构。
2、通过递归的方式实现二叉树的前、中、后序遍历算法,并对算法及思想简单应用,解决二叉树中的其它应用和实际问题中的应用。
3、求二叉树的深度
4、编写递归算法,计算二叉树中叶子结点的数目。
5*、通过非递归遍历的的方式实现二叉树的前、中、后序遍历算法和层次遍历算法。
6*、字符串的最长前缀匹配问题

二.代码实现

1、熟悉二叉树基本概念和存储结构,在实现二叉树的二叉链表存储结构。
// 内部节点类
public class BiTreeNode<T>{
    // 结点的数据域
    public T data;
    // 左右节点
    public BiTreeNode left,right;
    // 构造方法
    public BiTreeNode(T data, BiTreeNode left, BiTreeNode right) {
        this.data = data;
        this.left = left;
        this.right = right;
    }
}
// 二叉链式存储结构下的二叉树
public class BiTree <T>{

    // 树的根节点
    private BiTreeNode root;
    // 构造方法
    public BiTree(){
        this.root = null;
    }

    public BiTree(BiTreeNode root) {
        this.root = root;
    }
}
2、通过递归的方式实现二叉树的前、中、后序遍历算法,并对算法及思想简单应用,解决二叉树中的其它应用和实际问题中的应用。
/**
     * 先序遍历二叉树的递归算法
     * @param T
     */
    public void preRootTraverse(BiTreeNode T){
        if (T != null){
            // 先访问根节点
            System.out.println(T.data);
            // 再访问左子节点
            postRootTraverse(T.left);
            // 再访问右子节点
            postRootTraverse(T.right);
        }
    }
/**
     * 中序遍历二叉树的递归算法
     * @param T
     */
    public void inRootTraverse(BiTreeNode T){
        if (T != null){
            // 先访问左子节点
            inRootTraverse(T.left);
            // 再访问根节点
            System.out.println(T.data);
            // 在访问右子节点
            inRootTraverse(T.right);
        }
    }
/**
     * 后序遍历二叉树的递归算法
     * @param T
     */
    public void postRootTraverse(BiTreeNode T){
        if (T != null){
            // 先访问左子树
            postRootTraverse(T.left);
            // 再访问右子树
            postRootTraverse(T.right);
            // 再访问根节点
            System.out.println(T.data);
        }
}
3、求二叉树的深度
/**
     * 求二叉树的深度 (递归)
     * @param T
     * @return
     */
    public int getDepth(BiTreeNode T){
        if(T != null){
            int leftDepth = getDepth(T.left);
            int rightDepth = getDepth(T.right);
            return 1 + (leftDepth > rightDepth ? leftDepth:rightDepth);
        }
        return 0;
}
4、编写递归算法,计算二叉树中叶子结点的数目。
/**
     * 计算节点个数(递归)
     * @param T
     * @return
     */
    public int countNode(BiTreeNode T){
        // 采用先序遍历的方式对二叉树进行遍历,并计算其节点个数
        int count = 0;
        if (T != null){
            count++;
            count += countNode(T.left);
            count += countNode(T.right);
        }
        return count;
    }
5*、通过非递归遍历的的方式实现二叉树的前、中、后序遍历算法和层次遍历算法。
/**
     * 先序遍历二叉树的非递归算法
     */
    public void preRootTraverse(){
        BiTreeNode T = root;
        if (T != null){
            // 构造一个栈
            Stack stack = new Stack();
            // 根节点入栈
            stack.push(T);
            while (!stack.isEmpty()){
                // 移除栈顶节点,并访问其值
                T = (BiTreeNode) stack.pop();
                System.out.println(T.data);
                while(T != null){
                    // 访问左子结点
                    if (T.left != null){
                        System.out.println(T.left.data);
                    }
                    // 右子节点非空入栈
                    if (T.right != null){
                        stack.push(T.right);
                    }
                    // 继续左子节点
                    T = T.left;
                }
            }
        }
    }

/**
     * 中序遍历二叉树的非递归算法
     */
    public void inRootTraverse(){
        BiTreeNode T = root;
        if (T != null){
            // 构造一个栈
            Stack stack = new Stack();
            // 根节点入栈
            stack.push(T);
            while (!stack.isEmpty()){
                while(stack.peek() != null){
                    // 将栈顶元素的左子节点压入栈中
                    stack.push(((BiTreeNode)stack.pop()).left);
                }
                // 空节点退栈
                stack.pop();
                if (!stack.isEmpty()){
                    // 移除栈顶元素返回其值
                    T = (BiTreeNode) stack.pop();
                    System.out.println(T.data);
                    // 节点右子节点入栈
                    stack.push(T.right);
                }
            }
        }
    }

/**
     * 后序遍历二叉树的非递归算法
     */
    public void postRootTraverse(){
        BiTreeNode T = root;
        if (T != null){
            // 构造栈对象
            Stack stack = new Stack();
            // 根节点进栈
            stack.push(T);
            // 访问标记
            Boolean flag;
            // p指向刚被访问的节点
            BiTreeNode p =null;
            while (!stack.isEmpty()){
                while (stack.peek() != null){
                    // 将栈顶的节点的左子节点入栈
                    stack.push(((BiTreeNode) stack.pop()).left);
                }
                // 空节点退栈
                stack.pop();
                while(!stack.isEmpty()){
                    // 查看栈顶元素
                    T = (BiTreeNode) stack.peek();
                    if (T.right == null || T.left == null){
                        // 访问节点
                        System.out.println(T.data);
                        // 移除栈顶元素
                        stack.pop();
                        // p指向刚被访问的节点
                        p = T;
                        // 访问标记
                        flag = true;
                    }else {
                        // 右子节点入栈
                        stack.push(T.right);
                        // 未访问标记
                        flag = false;
                    }
                    if (!flag){
                        break;
                    }
                }
            }
        }
}

/**
     * 层序遍历二叉树算法
     */
    public void levelTraverse(){
        BiTreeNode T = root;
        if (T != null){
            // 创建一个队列
            Queue queue = new Queue();
            // 根结点入队列
            queue.enqueue(T);
            while(!queue.isEmpty()){
                T = (BiTreeNode)queue.dequeue();
                // 访问节点
                System.out.println(T.data);
                // 左结点非空,入队列
                if (T.left!=null){
                    queue.enqueue(T.left);
                }
                // 右节点非空,入队列
                if (T.right != null){
                    queue.enqueue(T.right);
                }
            }
        }
    }
6*、字符串的最长前缀匹配问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值