C语言 二叉查找树性质详解及实例代码

C语言二叉查找树性质详解及实例代码

什么是二叉查找树?

二叉查找树,也称二叉搜索树,它是一种基于对比的动态数据结构。它的定义如下:

  • 每个节点都包含一个键值,且键值唯一;
  • 每个节点的左子树只包含小于当前节点的节点;
  • 每个节点的右子树只包含大于当前节点的节点;
  • 左右子树都是二叉搜索树;

二叉查找树的性质

二叉查找树的性质体现在它的增、删、查等操作中,具体有以下几种性质:

  • 查找节点:在二叉查找树中查找一个节点,首先查找根节点,如果查找值等于根节点的键值,则查找结束;如果查找值小于根节点的键值,则在左子树中继续查找;如果查找值大于根节点的键值,则在右子树中继续查找。

  • 插入节点:在二叉查找树中插入一个节点,首先查找根节点,如果查找值等于根节点的键值,则插入失败;如果查找值小于根节点的键值,则在左子树中继续查找;如果查找值大于根节点的键值,则在右子树中继续查找,直到找到一个空节点,将新节点插入到该节点处。

  • 删除节点:在二叉查找树中删除一个节点,首先查找要删除的节点,如果该节点没有子节点,则直接删除;如果该节点只有一个子节点,则将该节点的子节点替换该节点;如果该节点有两个子节点,则用该节点的后继节点(即右子树中最小的节点)替换该节点,然后删除该后继节点。

  • 中序遍历:中序遍历二叉查找树可以得到一个递增的有序序列。

二叉查找树实现过程

以下是C语言实现二叉查找树的过程,包括插入和查找操作。

#include <stdio.h>
#include <stdlib.h>

/* 二叉查找树定义 */
typedef struct _node {
    int key;
    struct _node *left;
    struct _node *right;
} Node, *Tree;

/* 查找节点 */
Node* search(Tree t, int key) {
    if (t == NULL) {
        return NULL;
    }

    if (key == t->key) {
        return t;
    } else if (key < t->key) {
        return search(t->left, key);
    } else {
        return search(t->right, key);
    }
}

/* 插入节点 */
Node* insert(Tree t, int key) {
    /* 建立新节点 */
    Node *p = (Node*)malloc(sizeof(Node));
    p->key = key;
    p->left = NULL;
    p->right = NULL;

    /* 查找插入位置 */
    if (t == NULL) {
        t = p;
    } else if (key < t->key) {
        t->left = insert(t->left, key);
    } else if (key > t->key) {
        t->right = insert(t->right, key);
    }

    return t;
}

/* 中序遍历 */
void inorder(Tree t) {
    if (t != NULL) {
        inorder(t->left);
        printf("%d ", t->key);
        inorder(t->right);
    }
}

/* 测试入口 */
int main() {
    Tree t = NULL;

    t = insert(t, 5);
    t = insert(t, 3);
    t = insert(t, 7);
    t = insert(t, 1);
    t = insert(t, 9);

    Node *search_node = search(t, 7);
    if (search_node != NULL) {
        printf("Found node key=%d\n", search_node->key);
    } else {
        printf("Not found\n");
    }

    printf("Inorder traversal: ");
    inorder(t);

    return 0;
}

二叉查找树使用示例1

以下是一个示例代码,它演示了如何使用二叉查找树来存储整数,并输出各整数。

#include <stdio.h>
#include <stdlib.h>

/* 二叉查找树定义 */
typedef struct _node {
    int key;
    struct _node *left;
    struct _node *right;
} Node, *Tree;

/* 插入节点 */
Node* insert(Tree t, int key) {
    /* 建立新节点 */
    Node *p = (Node*)malloc(sizeof(Node));
    p->key = key;
    p->left = NULL;
    p->right = NULL;

    /* 查找插入位置 */
    if (t == NULL) {
        t = p;
    } else if (key < t->key) {
        t->left = insert(t->left, key);
    } else if (key > t->key) {
        t->right = insert(t->right, key);
    }

    return t;
}

/* 中序遍历 */
void inorder(Tree t) {
    if (t != NULL) {
        inorder(t->left);
        printf("%d ", t->key);
        inorder(t->right);
    }
}

/* 测试入口 */
int main() {
    Tree t = NULL;

    t = insert(t, 5);
    t = insert(t, 3);
    t = insert(t, 7);
    t = insert(t, 1);
    t = insert(t, 9);

    printf("Inorder traversal: ");
    inorder(t);

    return 0;
}

输出结果如下:

Inorder traversal: 1 3 5 7 9

二叉查找树使用示例2

以下是一个验证二叉查找树的例子,它演示了如何判断一个树是否是二叉查找树以及如何验证一个节点是否是其子树的最大最小值之间。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/* 二叉查找树定义 */
typedef struct _node {
    int key;
    struct _node *left;
    struct _node *right;
} Node, *Tree;

/* 插入节点 */
Node* insert(Tree t, int key) {
    /* 建立新节点 */
    Node *p = (Node*)malloc(sizeof(Node));
    p->key = key;
    p->left = NULL;
    p->right = NULL;

    /* 查找插入位置 */
    if (t == NULL) {
        t = p;
    } else if (key < t->key) {
        t->left = insert(t->left, key);
    } else if (key > t->key) {
        t->right = insert(t->right, key);
    }

    return t;
}

/* 中序遍历 */
void inorder(Tree t) {
    if (t != NULL) {
        inorder(t->left);
        printf("%d ", t->key);
        inorder(t->right);
    }
}

/* 验证二叉查找树 */
bool is_bst(Tree t, int min, int max) {
    if (t == NULL) {
        return true;
    }

    if (t->key <= min || t->key >= max) {
        return false;
    }

    return is_bst(t->left, min, t->key) && is_bst(t->right, t->key, max);
}

/* 测试入口 */
int main() {
    Tree t = NULL;

    t = insert(t, 5);
    t = insert(t, 3);
    t = insert(t, 7);
    t = insert(t, 1);
    t = insert(t, 9);

    printf("Inorder traversal: ");
    inorder(t);

    if (is_bst(t, INT_MIN, INT_MAX)) {
        printf("\nTree %p is a binary search tree\n", t);
    } else {
        printf("\nTree %p is NOT a binary search tree\n", t);
    }

    return 0;
}

输出结果如下:

Inorder traversal: 1 3 5 7 9 
Tree 0x7f9161401690 is a binary search tree

以上就是二叉查找树的介绍和示例代码,希望能够对读者理解和使用它有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言 二叉查找树性质详解及实例代码 - Python技术站

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

相关文章

  • Lua教程(六):编译执行与错误

    Lua教程(六):编译执行与错误 Lua是一门解释型脚本语言,它的源代码需要经过编译才能在计算机上运行。本篇教程将介绍如何编译和执行Lua代码,以及如何处理代码中的错误。 编译执行Lua代码 Lua交互模式 在安装了Lua解释器后,打开终端或命令行,输入lua命令即可进入Lua交互模式。在交互模式下,可以逐行输入Lua代码并立即执行,也可以使用dofile或…

    C 2023年5月23日
    00
  • Vue编写多地区选择组件

    下面是关于如何使用Vue编写多地区选择组件的完整攻略: 1. 安装和引入相关组件 首先,需要安装和引入Vue框架及相关组件,让我们先来安装Vue: npm install vue 然后,我们需要安装一些用于处理地区选择的相关组件,如vue-i18n、vue-select和vue-multiselect。 分别安装方法如下: npm install vue-i…

    C 2023年5月23日
    00
  • jQuery使用getJSON方法获取json数据完整示例

    下面是关于”jQuery使用getJSON方法获取json数据完整示例”的完整攻略: 1. 简介 在Web开发中,经常需要使用Ajax技术从服务器获取数据并进行显示或其他操作。其中,获取的数据可能是JSON格式的数据,应对这种需求,jQuery提供了一个getJSON()方法来处理JSON数据。 2. getJSON()方法说明 方法语法 $.getJSON…

    C 2023年5月23日
    00
  • C++消息队列(定义,结构,如何创建,发送与接收)

    下面是C++消息队列的完整攻略。 定义 C++消息队列是一种多线程之间通讯的方式,其实现了线程之间的异步通信机制。消息队列基于先进先出的原则,消息发送者将消息依次放入消息队列的尾部,消息接收者从队列的头部依次取出消息进行处理。 结构 消息队列的结构一般分为三个部分: 队列存储空间:为消息存储提供空间。 发送者:将消息放入队列中。 接收者:从队列中取出消息进行…

    C 2023年5月23日
    00
  • C++ class和struct到底有什么区别详解

    C++中的class和struct定义方式非常相似,都可以包含成员变量和成员函数,甚至可以互相继承。但实际上,class和struct还是存在一些差别的。下面从以下三个方面对它们进行详细的比较: 定义语法 在定义上,class和struct的语法非常相似,但是有一个小差别: // 定义class class MyClass { public: int a; …

    C 2023年5月23日
    00
  • C语言中字符串的两种定义方式详解

    C语言中字符串的两种定义方式详解 什么是字符串? 字符串(string)是由一串字符(character)组成的序列,其中每个字符占据一个字节。在C语言中,字符串以null字符(\0)结尾,因此任何一个字符串都都包含了一个null字符。null字符不是可打印字符,而是一个表示字符串结尾的特殊符号。 直接定义字符串 在C语言中,我们可以直接定义一个字符串,定义…

    C 2023年5月23日
    00
  • C语言动态顺序表实例代码

    接下来我将详细讲解 C 语言动态顺序表的实现过程。首先我们需要先了解顺序表的概念,顺序表是一种线性表的存储结构,它在物理上采用一组连续的内存空间来存储线性表的数据元素,并且对于顺序表的元素,我们可以按照元素下标进行随机存取。接下来我们就可以开始进行动态顺序表的实现了。 动态顺序表的实现 初步设计 首先我们需要先建立一个动态顺序表结构体,它包含了以下几个基本成…

    C 2023年5月30日
    00
  • C#中Json反序列化的实现方法

    C#中我们可以使用Json反序列化来将Json字符串转换成对应的对象。下面介绍C#中Json反序列化的实现方法: 准备工作 在进行Json反序列化前,我们需要引入Newtonsoft.Json库。使用NuGet包管理器进行安装,或者手动下载该库进行引入。 Install-Package Newtonsoft.Json -Version 13.0.1 反序列化…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部