从零开始学数据结构系列之第三章《二叉排序树代码部分》


回顾构建二叉排序树

在这里插入图片描述

  1. 首先,将8作为根节点
  2. 插入3,由于3小于8,作为8的左子树
  3. 插入10,由于10大于8,作为8的右子树
  4. 插入1,由于1小于8,进入左子树3,1又小于3,则1为3的左子树
  5. 插入6,由于6小于8,进入左子树3,6又大于3,则6为3的右子树
  6. 插入14,由于14大于8,进入右子树10,14又大于10,则14为10的右子树
  7. 插入4,由于4小于8,进入左子树3,4又大于3,进入右子树6,4还小于6,则4为6的左子树
  8. 插入7,由于7小于8,进入左子树3,7又大于3,进入右子树6,7还大于于6,则7为6的右子树
  9. 插入13,由于13大于8,进入右子树10,又13大于10,进入右子树14,13小于14,则13为14的左子树

经过以上的逻辑,这棵二叉排序树构建完成。
在这里插入图片描述
我们可以看出:

  • 只要左子树为空,就把小于父节点的数插入作为左子树
  • 只要右子树为空,就把大于父节点的数插入作为右子树
  • 如果不为空,就一直往下去搜索,直到找到合适的插入位置

了解了如何构建后,我们不禁要问,这有啥用呀?感觉没啥特别的地方呢?别急!我们马上揭晓!

我们对这棵二叉树进行中序遍历,看看会发生什么?你自己试一试!

没错,这棵二叉树中序遍历结果为:

在这里插入图片描述
根据以上思路,我们其实就可以写出代码了,构建的过程其实就是插入的过程:

void bstInsert(TreeNode** T, int data) 
{
	if(*T == NULL)
	{
		*T = (TreeNode*)malloc(sizeof(TreeNode));
		(*T)->data=data;
		(*T)->lchild=NULL;
		(*T)->rchild=NULL;
	}

	else if((*T)->data > data)
		bstInsert(&((*T)->lchild),data);
	else if((*T)->data == data)
		return;
	else
		bstInsert(&((*T)->rchild),data);
}

二叉排序树的查找操作

​   它既然也叫二叉查找树,那想必会非常方便我们查找吧!它的操作并不是把中序遍历的结果存入数组,然后在有序数组里查找,而是直接在树上查找。其操作与二分查找非常相似,我们来查找7试一试?(这里要说明以下:在正常的数据结构中,由于数据量很大,所以我们也不知道我们想要的元素在不在里面;同时也不知道每个元素具体是多少,只知道他们的大小关系。我们是在此基础上进行查找)

  1. 首先,访问根节点8
  2. 根据性质,7比8小,所以如果7存在,那应该在8的左子树那边,访问8的左子树
  3. 访问到了3,根据第2步的思想,访问3的右子树
  4. 访问到了6,继续访问6的右子树
  5. 访问到了7,刚好找到啦!

在这里插入图片描述

TreeNode* bstSearch(TreeNode* T,  int data) 
{
    if (T) {
        if (T -> data == data) {
            return T;
        }
        else if (data < T -> data) {
            return bstSearch(T -> lchild, data);
        }
        else {
            return bstSearch(T -> rchild, data);
        }
    }
    else {
        return NULL;
    }
}

总代码

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

typedef struct TreeNode {
    int data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
}TreeNode;

TreeNode* bstSearch(TreeNode* T,  int data) 
{
    if (T) {
        if (T -> data == data) {
            return T;
        }
        else if (data < T -> data) {
            return bstSearch(T -> lchild, data);
        }
        else {
            return bstSearch(T -> rchild, data);
        }
    }
    else {
        return NULL;
    }
}

void bstInsert(TreeNode** T, int data) 
{
	if(*T == NULL)
	{
		*T = (TreeNode*)malloc(sizeof(TreeNode));
		(*T)->data=data;
		(*T)->lchild=NULL;
		(*T)->rchild=NULL;
	}

	else if((*T)->data > data)
		bstInsert(&((*T)->lchild),data);
	else if((*T)->data == data)
		return;
	else
		bstInsert(&((*T)->rchild),data);


}

void preOrder(TreeNode* T) 
{
	if (T) 
	{
        printf("%d ", T -> data);
        preOrder(T -> lchild);
        preOrder(T -> rchild);
    }
}

int main() 
{
	int i = 0;
	int nums[] = {53,17,19,61,98,75,79,63,46,40};
	TreeNode* T = NULL;
    for (; i < (sizeof(nums)/sizeof(int)); i++)
	{
        bstInsert(&T, nums[i]);
    }
    preOrder(T);
    printf("\n");
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

往期回顾

1.【第一章】《线性表与顺序表》
2.【第一章】《单链表》
3.【第一章】《单链表的介绍》
4.【第一章】《单链表的基本操作》
5.【第一章】《单链表循环》
6.【第一章】《双链表》
7.【第一章】《双链表循环》
8.【第二章】《栈》
9.【第二章】《队》
10.【第二章】《字符串暴力匹配》
11.【第二章】《字符串kmp匹配》
12.【第三章】《树的基础概念》
13.【第三章】《二叉树的存储结构》
14.【第三章】《二叉树链式结构及实现1》
15.【第三章】《二叉树链式结构及实现2》
16.【第三章】《二叉树链式结构及实现3》
17.【第三章】《二叉树链式结构及实现4》
18.【第三章】《二叉树链式结构及实现5》
19.【第三章】《中序线索二叉树理论部分》
20.【第三章】《中序线索二叉树代码初始化及创树》
21.【第三章】《中序线索二叉树线索化及总代码》
22【第三章】《先序线索二叉树理论及线索化》
23【第三章】《先序线索二叉树查找及总代码》
24【第三章】《后续线索二叉树线索化理论》
25【第三章】《后续线索二叉树总代码部分》
26【第三章】《二叉排序树基础了解》

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的二叉排序树查找的代码实现,仅供参考: ```c // 定义二叉排序树结点 typedef struct BSTNode { int key; // 关键字 struct BSTNode *left; // 左子节点 struct BSTNode *right; // 右子节点 } BSTNode; // 插入一个结点到二叉排序树中 void insertBSTNode(BSTNode **root, int key) { if (*root == NULL) { // 如果根节点为空,则创建新结点 BSTNode *newNode = (BSTNode*)malloc(sizeof(BSTNode)); newNode->key = key; newNode->left = NULL; newNode->right = NULL; *root = newNode; } else { // 根节点不为空,则插入到左子树或右子树中 if (key < (*root)->key) { // 插入到左子树中 insertBSTNode(&(*root)->left, key); } else if (key > (*root)->key) { // 插入到右子树中 insertBSTNode(&(*root)->right, key); } } } // 在二叉排序树中查找指定关键字的结点 BSTNode* searchBSTNode(BSTNode *root, int key) { if (root == NULL) { // 未找到结点 return NULL; } else if (root->key == key) { // 找到结点 return root; } else if (key < root->key) { // 在左子树中查找 return searchBSTNode(root->left, key); } else { // 在右子树中查找 return searchBSTNode(root->right, key); } } ``` 使用时,可以先创建一个空的二叉排序树,然后逐个插入结点,最后在树中查找指定关键字的结点。例如: ```c int main() { BSTNode *root = NULL; // 插入结点 insertBSTNode(&root, 8); insertBSTNode(&root, 3); insertBSTNode(&root, 10); insertBSTNode(&root, 1); insertBSTNode(&root, 6); insertBSTNode(&root, 14); insertBSTNode(&root, 4); insertBSTNode(&root, 7); insertBSTNode(&root, 13); // 查找结点 BSTNode *node = searchBSTNode(root, 6); if (node != NULL) { printf("Found node: %d\n", node->key); } else { printf("Node not found.\n"); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值