、目的

  1. 掌握二叉查找树的基本概念及其基本操作的实现;

、环境:

operating system version:Win11

CPU instruction set:  x64

Integrated Development Environment:Viusal Studio 2022

、内容:

输入数据的第一行为一个正整数T,表示测试数据的组数,即共 T 组测试数据。每组测试数据的第一行输入正整数 n(5 ≤n ≤20),第二行输入n个整数,要求依次完成以下工作:

1)以这n个整数生成一棵用链式存储结构存储的二叉排序树

2)按递增顺序输出该二叉排序树中所有数

3)输入一个整数key ,对该二叉排序树进行查找,若在该二叉排序树中存在这个整数key ,则输出find ,否则输出not find;

4)输入一个整数key,若该二叉排序树中不存在这个整数key,则将key 插入到该二叉排序树中,使插入后仍为原性质的二叉排序树 否则不必插入;

5)在 4)的基础上,按递减顺序输出该二叉排序树中的所有数。

、要求:

1)实现二叉查找树的定义;

2)实现二叉查找树的查找、插入操作。

、步骤:

1.程序:

#include<stdio.h>
typedef struct node
{
int data;//定义数据域
struct node* lchild, * rchild;//指向左右结点的指针
} nodeb,*bitree;//定义二叉排序树的结点结构  void inOrder(bitree t, int* i)
{//中序遍历  if (t)  {  inOrder(t->lchild, i);   (*i)++;  if (*i == 1)  printf("%d ", t->data);  else  printf("%d ", t->data);  inOrder(t->rchild, i);  }
}  void destOrder(bitree t, int* i)
{//递减输出  if (t)  {  destOrder(t->rchild, i);  (*i)++;  if (*i == 1)  printf("%d ", t->data); else  printf("%d ", t->data);  destOrder(t->lchild, i);  }
}  void searchNode(bitree t, bitree* f, bitree* p, int key)
{  *p = t;   *f = NULL;  while (*p != NULL && ((*p)->data != key))   {//在二叉树t中查找整数为key的结点,若找到,则p指向该结点。  *f = *p;  if (key < (*p)->data) //寻找的key小于该数  *p = (*p)->lchild; //在左子树中寻找  else  (*p) = (*p)->rchild;//否则在右子树中寻找  }
}
bitree createBtree(int n)
{//建立有n个整数的二叉树  bitree p, q, f, t;   int i, d;  t = NULL;  for (i = 0; i < n; i++)   {  p = NULL;   scanf_s("%d", &d);  searchNode(t, &f, &p, d);  if (!p) //当该数在二叉排序树中不存在  {  q = new nodeb; //建立新节点  q->data = d; //并对该节点赋值  q->lchild = q->rchild = NULL; //令左右节点为空  if (f == NULL)  t = q;  else if (d < f->data)  f->lchild = q;   else  f->rchild = q;  }  }  return t;
}
int insertNode(bitree* t, int key)
{//在二叉排序树中插入key结点,返回操作结果情况  bitree p, f, s;  searchNode(*t, &f, &p, key);   if (!p)  {//思路同上  s = new nodeb;  s->data = key;  s->lchild = s->rchild = NULL;   if (!f)  *t = s;  else if (key < f->data)  f->lchild = s;  else  f->rchild = s; return 1;
}
else  return 0;
}  int main()
{  bitree t, p, f;  int d, j, n, key, i;  scanf_s("%d", &d);//输入数据的组数  for (j = 0; j < d; j++) {  scanf_s("%d", &n);  t = createBtree(n);  //调用createbintree()算法建立二叉排序树t  i = 0;  inOrder(t, &i);  //调用改进中序遍历按递增顺序输出该二叉排序树中的元素  printf("\n");  scanf_s("%d", &key);  searchNode(t, &f, &p, key);  //调用searchNode()算法查找要查找的整数  if (p)  printf("find\n");  //输出查找的结果  else  printf("not find\n");  scanf_s("%d", &key);  insertNode(&t, key);  i = 0;  //调用改进的遍历算法按递减顺序输出二叉排序树的元素  destOrder(t, &i);  printf("\n");  }  return 1;
}

2.程序结果:
程序运行,在此次、中我使用的测试数据如下:

3 //数据的组数
//第一组测试数据:
4
5 20 21 59
12
3

测试结果如下:
 
分析:可知,先输入该树共4个整数,调用createbintree()算法建立二叉排序树t,然后调用改进中序遍历按递增顺序输出该二叉排序树中的元素,再输入测试样例12,调用searchNode()算法查找到,该树的结点中无12,因此输出not find,再输入测试样例3,同样该树的结点中不存在3,因此将3插入树中,最后调用改进的遍历算法按递减顺序输出二叉排序树的元素为59 21 20 5 3。

//第二组测试数据:
5
20 22 5 2 13
13
14 

测试结果如下:
 
分析:先输入该树共5个整数,调用createbintree()算法建立二叉排序树t,然后调用改进中序遍历按递增顺序输出该二叉排序树中的元素,再输入测试样例13,调用searchNode()算法查找到,该树的结点中存在13,因此输出find,再输入测试样例14,同样该树的结点中不存在14,因此将14插入树中,最后调用改进的遍历算法按递减顺序输出二叉排序树的元素。

//第三组测试数据:
8
19 21 7 23 19 49 10 1
100
49

测试结果如下:
 
分析:先输入该树共8个整数,调用createbintree()算法建立二叉排序树t,然后调用改进中序遍历按递增顺序输出该二叉排序树中的元素,再输入测试样例100,调用searchNode()算法查找到,该树的结点中无100,因此输出not find,再输入测试样例49,该树的结点中存在49,因此无需插入,最后调用改进的遍历算法按递减顺序输出二叉排序树的元素。
由测试结果可知,算法实现了1)实现二叉查找树的定义;2)实现二叉查找树的查找、插入操作。

3.分析和改进:
        分析:此次、的整体思路是:首先建立二叉排序树,并且对于输入的关键字序列中的每一个整数,在正在建立的二叉排序树中查找是否已经存在该整数,若不存在,则由查找模块返回要增加结点位置的双亲结点,根据要建立的二叉排序树的性质,当要增加的整数比双亲结点的整数小的话就插到其左孩子的位置,否则插到其右孩子的位置。这样重复,直到输入结束。
在二叉排序树中进行查找的过程和二分查找类似,也是一个逐步缩小查找范围的过程。若查找成功,则是走了一条从根结点到待查结点的路径;若查找失败,则是走了一条根结点到某个叶子结点的路径。因此,查找过程中和关键字比较的次数不超过树的深度。这过程中,每进入子树前,保存当前结点,以便带回要增加结点的双亲结点。搜索直至找到要查找的整数,用一指针带回;或搜索直至叶子结点的下方,找不到要查找的整数而使空指针带回,以便判断要查找的整数是否找到。
由于含有n个结点的二叉排序树不唯一,形态和深度可能不同。故含有n个结点的二叉排序树的平均查找长度和树的形态有关。
        在递增输出的算法中,可以利用二叉排序树的一个巧妙性质,即通过中序遍历二叉搜索树得到的关键码序列是一个递增序列,以此实现递增输出。而在递减输出中,可以采用先遍历右子树,再输出结点,然后遍历左子树的方式实现递减序列的打印。
在插入算法中,在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。插入过程:若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。
        改进:在基于二叉排序树的查找算法里,最后得到的时间复杂度是在O(log2(n))到O(n)之间,但是当二叉排序树只有一颗子树的时候,排序二叉树的查找就退化成了顺序查找,因此算法的效率反而不高,发现可以控制二叉排序树,让二叉排序树的左右子树均衡一些,可以让二叉排序树的左右子树的节点数目相差的绝对值不超过1,就控制住了二叉排序树的左右子树均衡程度,使基于二叉排序树的查找不至于退化成了顺序查找。我查了一下,这就是平衡二叉排序树(AVL树)的思想,即平衡二叉排序树左右子树高度差的绝对值小于或者等于1,平衡二叉排序树的左右子树也是一颗平衡二叉排序树。它的基本实现原理为在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

六 、小结:
        此次是有关二叉排序树,二叉排序树是一种动态树表。 二叉排序树的定义:二叉排序树或者是一棵空树, 或者是一棵具有如下性质的二叉树: ⑴ 若它的左子树非空,则左子树上所有结点的值均小于根结点的值; ⑵ 若它的右子树非空,则右子树上所有结点的值均大于根结点的值; ⑶ 左、右子树本身又各是一棵二叉排序树。二叉排序树的性质: 按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列,在对遍历进行略微的改进后,实现了递减有序序列的输出。插入、查找算法在上一部分进行了详细地分析。最后,在算法的改进部分,我针对查找算法进行了分析,当二叉排序树只有一颗子树的时候,排序二叉树的查找就退化成了顺序查找,最坏情况下效率降至O(n),我找到了改进方案,即控制住二叉排序树的左右子树均衡程度,采用平衡二叉排序树(AVL树)的思想改进查找算法的时间复杂度。

二叉查找树的编程与实现 C语言相关推荐

  1. python和c哪个适合入门-编程入门选什么语言好?C 语言还是Python ?为你解析

    前面我分享过计算机行业已经成了学校选择排名第一,家长和学生都很看好计算机类专业.现在IT行业也越来越火爆,程序员越来越被人看好.面对相比同龄人高薪资的诱惑,人们很难不心动,即使秃头也值得! 那么问题来 ...

  2. “主要的编程范型”及其语言特性关系(多图)

    "主要的编程范型"(The principal programming paradigms)这幅图,其实出现得不算早,作者在2007年完成了该图的1.0版,到2008年更新至v1. ...

  3. 《快乐编程大本营》java语言训练班-第4课:java流程控制

    <快乐编程大本营>java语言训练班-第4课:java流程控制 第1节. 顺序执行语句 第2节. 条件分支语句:if条件语句 第3节. 条件分支语句:switch 条件语句 第4节. 条件 ...

  4. 二级c语言上机编程技巧,二级C语言上机编程题技巧总结

    二级C语言上机编程题技巧 一. 方法总结 1. 二级C语言上机编程题在二级上机考试中属于较难题型,因此很多同学都害怕通过不了.综合 往年的考试,结合考试大纲,每年考试的编程题都有一定的规律和方法,只要 ...

  5. c语言超长编程程序,全国青少年软件编程等级考试C语言经典程序题10道五

    全国青少年软件编程等级考试C语言经典程序题10道五 [程序41] 题目:学习static定义静态变量的用法 1.程序分析: 2.程序源代码: #include "stdio.h" ...

  6. c++经典编程题_全国青少年软件编程等级考试C语言经典程序题10道十

    全国青少年软件编程等级考试C语言经典程序题10道十 [程序91] 题目:时间函数举例1 1.程序分析: 2.程序源代码: #include "stdio.h" #include & ...

  7. 轻松学c语言编程.pdf等,轻松学编程 轻松学C语言编程pdf

    轻松学编程 轻松学C语言编程 内容简介 <轻松学编程:轻松学C语言编程>从初学者的角度出发,以通俗易懂的语言.丰富多彩的实例,详细介绍了使用C语言进行程序开发应该掌握的各方面知识.全书共1 ...

  8. C/C++ 编程中多国语言处理

    C/C++ 编程中多国语言处理 简介: 多国语言的存在,使程序员在编码处理上花费了大量时间和精力:然而各种各样的乱码问题,如 XML 格式错误.文本显示异常.解析器异常等依然层出不穷.特别的,相对于 ...

  9. 《快乐编程大本营》java语言训练班 1课:第一个java程序:你好,范冰冰;

    <快乐编程大本营>java语言训练班 1课:第一个java程序:你好,范冰冰: 1Java介绍 2安装java环境JDK 3安装web环境tomcat 4安装开发工具Idea2017 5编 ...

最新文章

  1. 37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...
  2. 【NLP招聘动态】太难啦!面试官盘点NLP近五年招聘动态
  3. 呵呵,又在这里开了个博客,现在已经有好几个了
  4. 命令查看java的class字节码文件、verbose、synchronize、javac、javap
  5. Redis Streams 介绍
  6. [HTML] Google IE-x.js 解决IEx与W3C标准的冲突
  7. docker 发布应用时添加 git revision
  8. Java反射 field
  9. Bootloader和App例程,实现M0基于UART的IAP升级功能,升级过程中通信中断,重新上电后Bootloader仍可运行。实现平台:STM32F030R8
  10. MVC4使用SignalR出现$.connection is undefined错误备忘
  11. BP神经网络算法简介
  12. 解密街头立体画的创作过程
  13. 两组数据的偏差率_GWT测试报告 篇七十五:隐患难忽视,RIVAL 3 WIRELESS精准度LOD测试...
  14. VRP和调度问题的主流精确算法和启发式算法
  15. ubuntu赋予当前用户root权限
  16. 猿创征文|OpenCV 如何提高条形码识别率
  17. linux shell 获取环境变量,bash shell中的环境变量
  18. 无法像唐骏一样地成功
  19. 基于JavaWEB的网上订餐系统设计与实现
  20. Java 学习笔记(导航目录)

热门文章

  1. Android中汉字转拼音的两种方法,优劣比较
  2. 【python日用】itertools.permutations用法
  3. hylan:安装aptitude(完整的软件包管理系统)遇到的问题
  4. linux 进程调度ppt,371Linux进程调度.PPT
  5. 挣1万,可能靠的是体力。挣10万,也许靠的是脑力。挣100万靠什么?
  6. Java读取txt文件:TSP问题测试算例att48.txt
  7. Maven配置阿里云Maven中央仓库
  8. kubernetes网络之---Calico原理解读
  9. 最新计算机专业毕设选题题目推荐
  10. 毕业设计 2023-2024年最新信息管理专业毕设选题题目推荐汇总