[二叉排序树] 插入相同元素的二叉排序树 | 递归与非递归 | 对结构体中指针的理解

本文主要是介绍[二叉排序树] 插入相同元素的二叉排序树 | 递归与非递归 | 对结构体中指针的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【题目】 设在一棵二叉排序树的每个结点中,含有关键字值key域和统计相同关键字值结点个数的count域
当向该树插入一个元素时
若树中已存在该元素的关键字值相同的结点,则使该结点的count域增1
否则就由该元素生成一个新结点并插入到树中,使其count域+1
【实质】 实现一个可以插入相同元素的二叉排序树-递归与非递归
【讨论】 递归与非递归中指针引用的问题

【结构体定义】

typedef struct BiTNode{int key;int count; //保存元素的个数struct BiTNode *lchild;struct BiTNode *rchild;
}BiTNode, *BiTree;

【对结构体中指针的理解】两种方法中:①递归方法的插入有效;②非递归方法的插入无效,主函数的T还是为NULL。这是为什么?

递归方法非递归方法

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

【问题】非递归能不能像递归那样取到rchild的位置?

【结果】

【完整代码】

#include<stdio.h>
#include<malloc.h>typedef struct BiTNode{int key;int count;struct BiTNode *lchild;struct BiTNode *rchild;
}BiTNode, *BiTree;void insert(BiTNode *&T, int key) {if (!T) {T = (BiTNode *)malloc(sizeof(BiTNode));T->key = key;T->count = 1;T->lchild=T->rchild=NULL;} else {if (T->key == key) ++T->count;else if (T->key < key) insert(T->rchild, key);else insert(T->lchild, key);}
}void insert_norecursion(BiTNode *&T,int key) {// 二叉排序树不需要开辟栈,不需要保存所有路径BiTNode *p = T; //当前指针BiTNode *pre = NULL; //p的父亲// 开始往下搜索while (p) {if (p->key == key) { //找到++p->count; //自增return ;} else { //没有找到,往下查找pre = p; //保留p的父亲if (p->key < key) p=p->rchild;else p=p->lchild;}}// p==NULL表示找到了新元素插入的位置,即为p的位置/* 但直接插入到p无效p = (BiTNode *)malloc(sizeof(BiTNode));p->key = key;p->count = 1;p->lchild=p->rchild=NULL;*/// 插入到p的父亲pre的下面BiTNode *s = (BiTNode *)malloc(sizeof(BiTNode));s->count=1;s->key=key;s->lchild=s->rchild=NULL;if (pre==NULL) //T为空树 T=s; else if (key < pre->key) //挂在pre的左树上pre->lchild = s; elsepre->rchild = s;
}// 按树状打印二叉树:https://geodoer.blog.csdn.net/article/details/82938306
void PrintAsTree(BiTree T, int i) { //i代表所在层次int j;if (T) {PrintAsTree(T->rchild, i+1); //访问右子树for (j=0; j<i-1; ++j) printf("\t");printf("%d(%d)\n",	T->key, T->count);PrintAsTree(T->lchild, i+1); //访问左子树}
}/* 测试数据
13
5 4 3 8 5 9 4 7 8 10 9 6 10
*/
int main() {int n;int key;BiTree T = NULL;// 递归scanf("%d", &n);while (n--) {scanf("%d", &key);insert(T, key);}PrintAsTree(T, 1);BiTree T2 = NULL;scanf("%d", &n);while (n--) {scanf("%d", &key);insert_norecursion(T2, key);}PrintAsTree(T2, 1);return 0;
}

这篇关于[二叉排序树] 插入相同元素的二叉排序树 | 递归与非递归 | 对结构体中指针的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/705474

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念