IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构与算法-树 -> 正文阅读

[数据结构与算法]数据结构与算法-树

一、数组、链表、树的比较

数组存储方式扥解析:

优点:通过下标方式访问元素,速度快,对于有序数组还可以使用二分查找提高检索速度

缺点:如果要检索具体某个值,或者插入值会整体移动,效率低。

链式存储方式分析:

优点:在一定程度上度数组存储方式有优化,比如插入一个数值时,只需要将插入点接入到链表中即可,删除效率也是同样效果好。

缺点:在进行检索时,效率低,检索某个值时,需要从链表头一直做检索。

树存储方式分析:

能提高数据存储,读取效率,比如二叉树既可以保证数据检索速度,同时也可以保证数据插入,删除,修改的速度

二、二叉树

1、概述

二叉树是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能见得转换为二叉树,二叉树的存储结构及其算法都比较简单。二叉树的特点是每个节点最多只能有两个子树,且有左右之分

?常用术语:结点、根结点、父结点、子结点、叶子结点(没有子结点的结点)、结点的权(结点值)、路径(从root结点找到目标结点的线路)、层、子树、树的高度(最大层数)、森林(多颗子树成森林)

右边的权值大于父结点,左边权值小于父结点

?满二叉树:如果该二叉树的所有叶子结点都在最后一层,并且结点总数是2^n-1,n是层数

?完全二叉树:二叉树的所有叶子结点都在最后一层或者倒数第二层,而且最后一层的叶子结点在左边连续,倒数第二层的叶子结点在右边连续。

2.二叉树的应用案例

①可以使用前序,中序,后序对下面的二叉树进行遍历(无参情况下)
1、 前序遍历:先输出父结点,在遍历左子树和右子树
2、 中序遍历:先遍历左子树,在遍历父结点,再遍历右子树
3、 后序遍历:先遍历左子树,再遍历右子树,最后遍历父结点
还有就是根据编号进行前序中序后序查询
Node
package com.mei.tree;

public class Node {
    private int no;
    private String name;
    private Node left;
    private Node right;

    public Node(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", left=" + left +
                ", right=" + right +
                '}';
    }
    /*
    * 定义前序遍历
    * */
    public  void preSelect(){
        //先出福结点
        System.out.println(this);
        if(this.left!=null){
            this.left.preSelect();
        }
        if(this.right!=null){
            this.right.preSelect();
        }
    }
    /*
    * 中序遍历结点*/
    public void infixSelect(){
        //左节点 父结点 右结点
        if (this.left!=null){
            this.left.infixSelect();
        }
        System.out.println(this);
        if (this.right!=null){
            this.right.infixSelect();
        }
    }
    //后序遍历
    public void postSelect(){
        //左右父
        if (this.left!=null){
            this.left.infixSelect();
        }

        if (this.right!=null){
            this.right.infixSelect();
        }
        System.out.println(this);
    }

    //根据编号查询
    /*
     * 前序遍历查找
     */
    public Node preSearch(int no){
        /*
         * 判断是否是当前结点
         */
        if (this.no == no){
            return this;
        }
        /*
         * 判断当前结点的左子结点是否为空,如果不是空,则递归前序查找
         如果左递归前序查找,找到结点,则返回
         */
        Node lNode = null;
        if (this.left !=null){
            lNode = this.left.preSearch(no);
        }
        if (lNode !=null){
            return lNode;
        }
        /*
         * 左递归前序查找,找到结点,则返回否则继续判断
         *
         * 当前的结点的右子结点是否为空,如果不空,则继续像右递归前序查找
         */
        if (this.right !=null){
            lNode = this.right.preSearch(no);
        }
        return lNode;
    }
    /*
     * 中序遍历查找
     */
    public Node infixSearch(int no){
        /*
         * 判断当前结点左子结点是否为空,如果不为空,则递归中序查找
         */
        Node node = null;
        if (this.left !=null){
            node = this.left.infixSearch(no);
        }
        if (node !=null){
            return node;
        }
        if (this.no == no){
            return this;
        }
        if (this.right !=null){
            node = this.right.infixSearch(no);
        }
        return node;
    }
    /*
     * 后序遍历查找
     */
    public Node postSearch(int no){
        Node node = null;
        if (this.left !=null){
            node = this.left.postSearch(no);
        }
        if (node !=null){
            return node;
        }
        /*
         * 如果左边子树没有找到,则向右边子树递归进行后序遍历查找
         */
        if (this.right !=null){
            node = this.right.postSearch(no);
        }
        if (node !=null){
            return node;
        }
        /*
         * 如果左右子树都没有找到,那么判断当前结点是否是呢
         */
        if (this.no==no){
            return this;
        }
        return node;
    }
}


BinaryTree

package com.mei.tree;

public class BinaryTree {
      private Node root;
    public void setRoot(Node root) {
        this.root = root;
    }
    public void preSelect(){
        if (this.root !=null){this.root.preSelect();
        }else {
            System.out.println("二叉树为空,无法遍历");
        }
    }
    public void infixSelect(){
        if (this.root !=null){
            this.root.infixSelect();
        }else {
            System.out.println("二叉树为空,无法遍历");
        }
    }
    public void postSelect(){
        if (this.root !=null){
            this.root.postSelect();
        }else {
            System.out.println("二叉树为空,无法遍历");
        }
    }
    /*
     * 前序
     */
    public Node preNode(int no){
        if (root !=null){
            return root.preSearch(no);
        }else {
            return null;
        }
    }
    /*
     * 中序
     */
    public Node infixNode(int no){
        if (root !=null){
            return root.infixSearch(no);
        }else {
            return null;
        }
    }
    /* 后序
     */
public Node postNode(int no){
    if (root !=null){
        return root.postSearch(no);
    }else {
        return null;
    }
}

}

②删除结点

Node

/*删除结点两种情况
    1、删除的结点是叶子结点
    2、删除的结点是子树。非叶子结点
    * */
    public void delNode(int no){
        /*
         * 注意:
         *
         1、二叉树是单向的,所以我们是判断当前结点的子结点是否需要删除,而不能去判断当前这个结点是不是需要删除结点
         * 2、如果当前结点左子结点不为空,并且左子结点就是需要删除的结点,则将this.left = null,返回即可
         * 3、如果当前结点右子结点不为空,并且右子结点就是需要删除的结点,就将this.right = null,返回即可
         * 4、如果2,3步没有执行,那么需要向左子树进行递归删除
         * 5、如果第4步也没有删除结点,则向右子树进行递归删除
         */
        if (this.left!=null&&this.left.no==no){
            this.left=null;
            return;
        }
        if(this.right!=null&&this.right.no==no){
            this.right=null;
            return;
        }
        /*
        * 向左子树进行递归删除*/
        if (this.left!=null){
            this.left.delNode(no);
        }
        /*
        * 向右子树进行递归删除
        * */
        if(this.right!=null){
            this.right.delNode(no);
        }


    }

BinaryTree

/*
* 删除结点 */
public void delNode(int no){
        if (root !=null){
            if (root.getNo()==no){
                root = null;
            }else {
                root.delNode(no);
            }
        }else {
            System.out.println("树为空,不能操作删除");
        }
    }

3.二叉排序树

二叉排序树又称二叉查找树,也称二叉搜索树,查询效率比链表结构要高。如果有相同的值,可以将该节点放在左子结点和右子结点。同一数据对应的二叉排序树不唯一。但经过终须遍历得到的关键码序列都是一个递增序列。

二叉排序树的创建和遍历

package com.mei.binarysort;

public class Node {
    public int value;
    public Node left;
    public Node right;
    public Node (int value){
        this.value=value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }
    /*public Node search(int value){
        if (value == this.value){
            return this;
        }
        else if (value< this.value){//如果小于当前结点,则向左子树递归查询
            //如果左子树结点为空
            if (this.left == null){
                return null;
            }return this.left.search(value);
        }
        else
        {//如果大于当前结点,则向左子树递归查询
            if (this.right == null){
                return null;
            }return this.right.search(value);
        }
    }*/


    public void add(Node node){
        if (node == null){
            return;
        }
        //判断传入的节点值与当前节点值关系
        if (node.value< this.value){
            if (this.left == null){
                this.left = node;
            } else
            {//向当前节点左子树递归
                this.left.add(node);
            }
        } else {//添加的结点值大于当前结点值
            if (this.right == null){
                this.right = node;
            } else {this . right .add(node);
            }
        }
    }


}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-01 11:47:26  更:2021-11-01 11:47:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:47:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码