C语言 超详细总结讲解二叉树的概念与使用

C语言 超详细总结讲解二叉树的概念与使用

1. 什么是二叉树?

二叉树是一种树状数据结构,其中每个节点最多有两个子节点,被称为左子节点和右子节点。具有以下几个特点:

  • 每个节点最多有两个子节点;
  • 左子节点可以为空,右子节点也可以为空;
  • 二叉树的每个节点最多有一个父节点;
  • 二叉树通常定义为递归模式定义,即每个节点都可以看做一棵新的二叉树。

2. 二叉树的遍历方式

二叉树的遍历方式分为三种:

  • 前序遍历:先访问根节点,然后遍历左子树,最后遍历右子树;
  • 中序遍历:先遍历左子树,然后访问根节点,最后遍历右子树;
  • 后序遍历:先遍历左子树,然后遍历右子树,最后访问根节点。

3. 二叉树的实现

在 C 语言中,我们通常会使用结构体去实现二叉树,结构体包含节点的值,左子节点指针和右子节点指针。示例如下:

typedef struct node{
    int val;            // 节点的值
    struct node* left;  // 左子节点指针
    struct node* right; // 右子节点指针
}node;

node* createNode(int val){  // 创建新节点
    node* newNode = (node*)malloc(sizeof(node));
    newNode->val = val;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

4. 二叉树的操作

4.1 插入节点

在二叉树中插入节点通常需要先找到要插入的位置。如果要插入的节点的值小于当前节点的值,那么我们就去找左子树;如果要插入的节点的值大于当前节点的值,那么我们就去找右子树。当找到一个空节点时,就把要插入的节点放在这个空节点上。

void insert(node** root, int val){
    if(*root == NULL){  // 如果根节点为空,直接放置新节点
        *root = createNode(val);
    }else if(val <= (*root)->val){  // 如果要插入的节点的值小于当前节点的值,那么我们就去找左子树
        insert(&((*root)->left), val);
    }else{  // 如果要插入的节点的值大于当前节点的值,那么我们就去找右子树
        insert(&((*root)->right), val);
    }
}

4.2 查找节点

查找节点的方式与插入节点类似,如果要查找的节点的值小于当前节点的值,那么我们就去找左子树;如果要查找的节点的值大于当前节点的值,那么我们就去找右子树。如果找到该节点,就返回该节点的指针;如果找不到该节点,就返回 NULL。

node* search(node* root, int val){
    if(root == NULL || root->val == val){  // 如果根节点为空或根节点的值就是要查找的值,就返回根节点
        return root;
    }else if(val < root->val){  // 如果要查找的节点的值小于当前节点的值,那么我们就去找左子树
        return search(root->left, val);
    }else{  // 如果要查找的节点的值大于当前节点的值,那么我们就去找右子树
        return search(root->right, val);
    }
}

4.3 删除节点

删除节点通常需要分三种情况讨论:

  • 要删除的节点是叶子节点,直接删除即可;
  • 要删除的节点只有一个子节点,把子节点传给其父节点即可;
  • 要删除的节点有两个子节点,需要找到右子树的最小节点并将其传给要删除的节点的位置。
node* delete(node* root, int val){
    if(root == NULL){  // 如果根节点为空,直接返回
        return NULL;
    }else if(val == root->val){  // 如果要删除的节点就是根节点
        if(root->left == NULL){  // 如果左子节点为空,就返回右子节点
            return root->right;
        }else if(root->right == NULL){  // 如果右子节点为空,就返回左子节点
            return root->left;
        }else{  // 找到右子树的最小节点并将其传给要删除的节点的位置
            node* minNode = findMin(root->right);
            root->val = minNode->val;
            root->right = delete(root->right, minNode->val);
        }
    }else if(val < root->val){  // 如果要删除的节点的值小于当前节点的值,那么我们就去找左子树
        root->left = delete(root->left, val);
    }else{  // 如果要删除的节点的值大于当前节点的值,那么我们就去找右子树
        root->right = delete(root->right, val);
    }
    return root;
}

5. 二叉树的示例

5.1 插入和查找节点

int main(){
    // 创建二叉树
    node* root = NULL;
    insert(&root, 10);
    insert(&root, 5);
    insert(&root, 20);
    insert(&root, 3);
    insert(&root, 7);
    insert(&root, 15);
    insert(&root, 25);

    // 查找节点
    node* n = search(root, 7);
    if(n != NULL){
        printf("Node found: %d\n", n->val);
    }else{
        printf("Node not found.\n");
    }

    // 插入节点
    insert(&root, 12);

    // 查找节点
    n = search(root, 12);
    if(n != NULL){
        printf("Node found: %d\n", n->val);
    }else{
        printf("Node not found.\n");
    }

    return 0;
}

输出:

Node found: 7
Node found: 12

5.2 删除节点

int main(){
    // 创建二叉树
    node* root = NULL;
    insert(&root, 10);
    insert(&root, 5);
    insert(&root, 20);
    insert(&root, 3);
    insert(&root, 7);
    insert(&root, 15);
    insert(&root, 25);

    // 删除节点
    root = delete(root, 5);

    // 查找节点
    node* n = search(root, 5);
    if(n != NULL){
        printf("Node found: %d\n", n->val);
    }else{
        printf("Node not found.\n");
    }

    return 0;
}

输出:

Node not found.

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言 超详细总结讲解二叉树的概念与使用 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C++高级数据结构之线段树

    C++高级数据结构之线段树攻略 什么是线段树 线段树是一种数据结构,它可以支持区间查询和单点修改,是处理静态区间问题的常用手段。它利用了 二分思想,将区间离散化成一些个体,然后考虑对个体进行处理,再结合区间合并的特性,更新区间信息。线段树主要由四个操作构成:建树、单点修改、区间查询和区间修改。 线段树的数据表示 在实现线段树时,我们需要考虑数据结构的几个要素…

    数据结构 2023年5月17日
    00
  • 一、对系统理论的认识

           经过一周的时间学习,我们知道了系统的定义:是一个由一组相互连接的要素构成的,能够实现某个目标的整体,任何一个系统都包括三种构成要件:要素连接,功能或目标。       1.系统的连接使得系统呈现特定的结构,使得系统的各个部件连接而产生系统特有的功能—相关性导新功能涌现。连接的媒介—“三流”(信息流,能量流,物质流)。       2.系统的静态…

    算法与数据结构 2023年4月18日
    00
  • 栈(Stack)

    概述 栈就是一种 只允许在表尾进行插入和删除操作 的 线性表 栈的特点 先进后出 ,在表尾进行插入和删除操作 数组实现栈 crown crown:使用bottom来确定栈顶所在数组的下标,默认为 -1 空栈 当空栈时 ,crown = -1 栈是否为空 当 crown = -1 时 ,栈为空 ,不能 遍历 ,出栈 , 获取栈顶元素 栈是否已满 当 crown…

    算法与数据结构 2023年4月19日
    00
  • C语言全面梳理结构体知识点

    C语言全面梳理结构体知识点 什么是结构体? 结构体是一种自定义的数据类型,它可以包含多个不同类型的成员变量,并且这些成员变量可以通过一个变量名来访问。结构体的定义需要使用关键字struct,并且需要指定结构体的类型名和成员变量。例如: struct Person { char name[20]; int age; float height; }; 以上代码就…

    数据结构 2023年5月17日
    00
  • Java面试题冲刺第十九天–数据库(4)

    本篇攻略是针对Java数据库相关面试题的,为了方便浏览,我将其分为以下几个部分: 1. 数据库连接池 在Java开发中,我们使用JDBC连接数据库进行数据操作时,为了提高数据库访问性能,通常会使用数据库连接池技术。常见的数据库连接池有:C3P0、Druid、HikariCP等。 C3P0 C3P0是一个开源的数据库连接池,可以设置最大连接数、最小连接数、最大…

    数据结构 2023年5月17日
    00
  • Java数据结构之双端链表原理与实现方法

    Java数据结构之双端链表原理与实现方法 一、什么是双端链表? 双端链表是一种链式数据结构,它每个节点都有两个指针:一个指向前一个节点,一个指向后一个节点。它具有链表的所有特点,而且还有一些独特的优点:对于一个双向链表,我们可以从头到尾遍历,也可以从尾到头遍历。在某些情况下,它比单向链表更有用,因为它可以执行逆序遍历。 二、双端链表的原理 双端链表由节点构成…

    数据结构 2023年5月17日
    00
  • Mysql 数据库结构及索引类型

    好的。首先,我们需要了解 Mysql 数据库的基本结构和索引类型。 Mysql 数据库结构 Mysql 数据库包含多个数据库,每个数据库包含多个数据表,每个数据表包含多个数据记录(或者叫行)。关键的概念包括数据库、数据表、数据记录以及 Mysql 列类型等。 数据库 Mysql 数据库是一个命名的容器,用于存储和管理相关数据表。可以使用以下 SQL 代码来创…

    数据结构 2023年5月17日
    00
  • Go select使用与底层原理讲解

    标题:Go select使用与底层原理讲解 标准库提供的go语言引擎的选择器select语法是并发编程中常用的语法之一,它允许协程同时等待多个IO操作的完成,通常会和通道配合使用。在本文中,我们将详细讲解Go select的使用和底层原理。 Go select的使用 基本语法 在Go语言中,select语法的基本语法如下: select { case &lt…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部