首页 > 其他分享 >树与二叉树

树与二叉树

时间:2024-07-17 21:53:20浏览次数:16  
标签:node root 二叉树 new data 节点

树与二叉树

目录

基本概念

树是一种非线性结构,一组数据中除了第一个节点,任意节点有且仅有一个直接前驱,有零哥=个或多个直接后驱,该组数据形成了一棵树,为一对多的数据关系。

基本术语

树的第一个节点,没有直接前驱。

双亲结点

某节点的直接前驱节点称为该节点的双亲节点。

孩子节点

某节点的直接后继节点称为孩子节点。

节点的层次

根节点点所在节点规定为第一层,其孩子所在层次称为第二层,以此类推。

节点的度

一个节点拥有的孩子节点的总数,称为该节点的度。

叶子

一棵树中结点的度等于0的节点,称为叶子,又叫终端节点。

树的高度

一棵树中所有节点的层次的最大值,称为这棵树的高度,又叫深度。

有序树与无序树

一棵树中,如果某个节点孩子节点之间是有序的(不可进行交换),称为有序树,否则为无序树。

二叉树

二叉树概念:

1.有序树

2.任意节点的度小于等于2(一个节点最多两个孩子)

二叉树基本特性

1.第I层上,最多有2^(i-1)个节点

2.高度为k的二叉树,最多有2^(k-1)个节点。

3.叶子数目为n0,度为2的的节点的节点数目为n2。则有n0=n2+1。

满二叉树/完美二叉树:

高度为K的树,节点总数为2^k-1.

完全二叉树:

节点标号连续(从上到下,从左到右)

平衡二叉树:

任意节点的两棵子树高度差小于一。

退化二叉树:

所有节点的度小于等于1,退化为链表。

二叉树的链式存储

typedef struct node
{
    datatype data; // 用户数据  数据域

    struct node *lchild; // 左孩子树指针
    struct node *rchild; // 右孩子树指针
}node;

树的遍历

前序遍历(根---左---右)、中序遍历(左--根---右)、后序遍历(左---右---根)。

按层遍历:从上到下,从左到右依次访问节点

前中后序遍历都是递归算法。

BST树

基本概念

搜索二叉树/二叉排序树/二叉查找树:将数据节点按照某种规律形成的一颗二叉树

提高搜索效率:小中大的归率存储/大中小

插入节点

// 假设 BST 节点存储的数据类型是 int
node *newNode(int data)
{
    // 准备好新节点,并将数据填入其中
    node *new = (node *)malloc(sizeof(node));
    if(new != NULL)
    {
        new->data = data;
        new->lchild = NULL;
        new->rchild = NULL;
    }
    return new;
}
// 将新节点new插入到一棵以 root 为根的 BST 中
// 插入节点后,返回新的 BST 的根
node *bstInsert(node *root, node *new)
{
    // 若此时 BST 为空,则返回 new 使之成为二叉树的根节点
    if(root == NULL)
        return new;

    // 若新节点比根节点小,那么新节点应该插入左子树中
    // 至于插入到左子树的具体什么位置就不用管了,直接递归即可
    if(new->data < root->data)
        root->lchild = bstInsert(root->lchild, new);

    // 若新节点比根节点大,那么新节点应该插入右子树中,直接递归即可
    else if(new->data > root->data)
        root->rchild = bstInsert(root->rchild, new);

    // 若已存在,则不处理  数据不允许相同
    else
    {
        printf("%d已存在\n", new->data);
        free(new);
    }

    return root;
}

删除节点

// 将数据(以整型为例)data从二叉树中删除
// 并返回删除之后的二叉树的根
node *bstRemove(node *root, int data)
{
    node *tmp = NULL;
    
    if(root == NULL)
        return NULL;

    // 若data小于根节点,则递归地在左子树中删除它
    if(data < root->data)
        root->lchild = bstRemove(root->lchild, data);

    // 若data小于根节点,则递归地在左子树中删除它
    else if(data > root->data)
        root->rchild = bstRemove(root->rchild, data);

    //找到相同的数据 
    else
    {
        // a. 根节点若有左子树,则用左子树中最大的节点max替换根节点
        //    并在左子树中递归删除max  
        if(root->lchild != NULL)
        {
            node *max;
            for(max=root->lchild; max->rchild!=NULL;
                max=max->rchild);

            root->data = max->data;
            root->lchild = bstRemove(root->lchild, max->data);
        }

        // b. 否则,若有右子树,则用右子树中最小的节点min替换根节点
        //    并在右子树中递归删除min  
        else if(root->rchild != NULL)
        {
            for(tmp=root->rchild; tmp->lchild!=NULL;
                tmp=tmp->lchild);

            root->data = tmp->data;
            root->rchild = bst_remove(root->rchild, tmp->data);
        }

        // c. 否则,直接删除节点
        else
        {
            free(root);
            return NULL;
        }
    }

    return root;
}

遍历代码

// 前序遍历
void preOrder(node *root)
{
    if(root == NULL)
        return;

    // 先访问根节点
    printf("%d", root->data);

    // 再依次使用前序算法,遍历其左、右子树
    preOrder(root->lchild);
    preOrder(root->rchild);
}

// 中序遍历
void inOrder(node *root)
{
    if(root == NULL)
        return;

    // 先访问左子树
    inOrder(root->lchild);

    // 再访问根节点
    printf("%d", root->data);

    // 再访问右子树
    inOrder(root->rchild);
}

// 后序遍历
void postOrder(node *root)
{
    if(root == NULL)
        return;

    // 先依次使用后序算法,遍历其左、右子树
    postOrder(root->lchild);
    postOrder(root->rchild);

    // 再访问根节点
    printf("%d", root->data);
}

标签:node,root,二叉树,new,data,节点
From: https://www.cnblogs.com/8866880c/p/18308352

相关文章

  • 题解:P10722 [GESP202406 六级] 二叉树
    题意一颗\(n\)节点的二叉树,每个节点非黑即白,给你\(Q\)次操作,每次给你一个\(u\),把\(u\)的子树内所有节点颜色反转,问最终每个节点的颜色。分析看到数据范围,首先把操作离线。容易发现如果一个节点重复操作奇数次,等效于操作一次,如果重复操作偶数次,等效于没操作。所以我们可......
  • leetcode145. 二叉树的后序遍历,递归法+迭代法,全过程图解+步步解析,一点点教会你迭代法
    leetcode145.二叉树的后序遍历,递归法+迭代法给你一棵二叉树的根节点root,返回其节点值的后序遍历。示例1:输入:root=[1,null,2,3]输出:[3,2,1]示例2:输入:root=[]输出:[]示例3:输入:root=[1]输出:[1]递归法还是一如既往的简单。postorder函数是递归函数,用......
  • 「代码随想录算法训练营」第十三天 | 二叉树 part3
    110.平衡二叉树题目链接:https://leetcode.cn/problems/balanced-binary-tree/题目难度:简单文章讲解:https://programmercarl.com/0110.平衡二叉树.html视频讲解:https://www.bilibili.com/video/BV1Ug411S7my题目状态:通过思路:采用递归的方式,遍历每个节点的左右孩子的深度......
  • Day 15 二叉树part03
    110.平衡二叉树classSolution{publicbooleanisBalanced(TreeNoderoot){if(root==null)returntrue;returnisBalanced(root.left)&&isBalanced(root.right)&&Math.abs(hight(root.left)-hight(root.right))......
  • 代码随想录算法训练营第14天 | 复习二叉树翻转
    2024年7月17日递归法翻转二叉树易错:要考虑节点为空的情况,以及写好边界条件。/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.va......
  • 二叉树 部分定义与性质
    针对于知识回顾/复习,发现一些博客对于一些名词的定义各不相同,于是自己对于部分容易混淆的定义作一个简单的记录。详细关于二叉树的内容可以看:二叉树-Hello算法,部分博客内容来自其中。名词定义1.层层(Level):二叉树中的所有节点可以根据与根节点的距离分成不同的层次。根节点位......
  • LeetCode第257题:二叉树的所有路径的Java实现
    摘要LeetCode第257题要求生成二叉树的所有从根节点到叶子节点的路径。本文将介绍两种Java解决方案:迭代法和递归法。1.问题描述给定一个二叉树的根节点,按照从根到叶的顺序遍历所有路径,并将它们作为列表的列表返回。2.示例分析输入:[1,2,3,null,null,4]'输出:[[1,2],[1,......
  • 代码随想录刷题Day 14 二叉树part02
    226.翻转二叉树//这道题其实就是遍历二叉树,然后交换每个节点的左右子节点即可。这里我就使用了一个栈来存储需要遍历的节点,每次循环弹出一个,然后交换其左右子节点就好了classSolution{publicTreeNodeinvertTree(TreeNoderoot){Stack<TreeNode>stack=new......
  • 【Java--数据结构】二叉树
    欢迎关注个人主页:逸狼创造不易,可以点点赞吗~如有错误,欢迎指出~树结构树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合注意:树形结构中,子树之间不能有交集,否则就不是树形结构常见概念  节点的度:一个节点含有子树的个数,如A的度为6......
  • 利用递归的二叉树的先序,中序,后序遍历
    一.常见的二叉树的遍历①先序遍历:先访问根节点,再访问左右子树(根左右)③中序遍历:先访问左子树,再访问根节点,最后访问右子树(左根右)③后序遍历:先访问左右子树,再访问根节点(左右根)先定义二叉树的数据结构:typedefcharElemType;typedefstructBTNode{ ElemTypedata; ......