排序二叉树

参考

Binary Search Tree Visualization (usfca.edu)

一、构建排序二叉树

注意引用 tree

/*** 构造二叉排序树* @param tree* @param x*/
void buildTree(BSTree &tree,ElementType &x){if (tree==NULL){tree=(BSTree) calloc(1, sizeof(BSTNode));tree->data=x;//注意return;}if (x>tree->data){buildTree(tree->rchild,x);}if (x<tree->data){buildTree(tree->lchild,x);}if (x==tree->data){return;}
}

二、查询排序二叉树的目标节点

注意引用 tree

//查找
int getPosition(BSTree &tree,int postion,ElementType x){if (tree!=NULL&&x==tree->data){return tree->data;}if (x>tree->data){return getPosition(tree->rchild,0,x);} else{return getPosition(tree->lchild,0,x);}
}

三、删除二叉排序树的节点

注意引用

注意左子树右子树都不为空的情况  删除的时候递归删除 因为我们不知道它的父亲节点

注意记得删除前改变被删除的位置的地址

//删除节点
void delTNode(BSTree &tree,ElementType x){if (tree==NULL){return;}BSTNode *temp=tree;if (x>temp->data){delTNode(tree->rchild,x);}if (x<temp->data){delTNode(tree->lchild,x);}if (x==temp->data){if (temp->lchild==NULL&&temp->rchild!=NULL){//注意记得改变此时被删除的位置的地址tree=temp->rchild;free(temp);}if (temp->rchild==NULL&&temp->lchild!=NULL){//注意记得改变此时被删除的位置的地址tree=temp->lchild;free(temp);}if (temp->lchild==NULL&&temp->rchild==NULL){//注意记得改变此时被删除的位置的地址tree=NULL;free(temp);}if (temp->lchild!=NULL&&temp->rchild!=NULL){//左右子树都不为空//找左子树的左右边//或者找右子树的最左边来代替temp=temp->lchild;while (temp->rchild!=NULL){temp=temp->rchild;}tree->data=temp->data;//因为这时候有俩个一样的值了 我们要确认我们要删除的是哪个值//因此这里应该删除这个节点的左子树上那个替死鬼delTNode(tree->lchild,temp->data);}}
}

 四、完整代码

#include <stdio.h>
#include <stdlib.h>typedef int ElementType;typedef struct BSTNode{ElementType data;BSTNode *rchild;BSTNode *lchild;
}BSTNode,*BSTree;/*** 构造二叉排序树* @param tree* @param x*/
void buildTree(BSTree &tree,ElementType &x){if (tree==NULL){tree=(BSTree) calloc(1, sizeof(BSTNode));tree->data=x;//注意return;}if (x>tree->data){buildTree(tree->rchild,x);}if (x<tree->data){buildTree(tree->lchild,x);}if (x==tree->data){return;}
}//查找
int getPosition(BSTree &tree,int postion,ElementType x){if (tree!=NULL&&x==tree->data){return tree->data;}if (x>tree->data){return getPosition(tree->rchild,0,x);} else{return getPosition(tree->lchild,0,x);}
}//删除节点
void delTNode(BSTree &tree,ElementType x){if (tree==NULL){return;}BSTNode *temp=tree;if (x>temp->data){delTNode(tree->rchild,x);}if (x<temp->data){delTNode(tree->lchild,x);}if (x==temp->data){if (temp->lchild==NULL&&temp->rchild!=NULL){//注意记得改变此时被删除的位置的地址tree=temp->rchild;free(temp);}if (temp->rchild==NULL&&temp->lchild!=NULL){//注意记得改变此时被删除的位置的地址tree=temp->lchild;free(temp);}if (temp->lchild==NULL&&temp->rchild==NULL){//注意记得改变此时被删除的位置的地址tree=NULL;free(temp);}if (temp->lchild!=NULL&&temp->rchild!=NULL){//左右子树都不为空//找左子树的左右边//或者找右子树的最左边来代替temp=temp->lchild;while (temp->rchild!=NULL){temp=temp->rchild;}tree->data=temp->data;//因为这时候有俩个一样的值了 我们要确认我们要删除的是哪个值//因此这里应该删除这个节点的左子树上那个替死鬼delTNode(tree->lchild,temp->data);}}
}//中序遍历 对于二叉排序树来说中序遍历就是从小到大依次排序
void inOrder(BSTree tree){if (tree==NULL){return;}inOrder(tree->lchild);printf("%3d",tree->data);inOrder(tree->rchild);
}int main() {BSTree tree;ElementType str[7]={56,20,30,1,3,78,9};//注意tree=(BSTree) calloc(1, sizeof(BSTNode));tree->data=56;for (int i = 1; i < 7; ++i) {buildTree(tree,str[i]);}ElementType x;x=getPosition(tree,0,1);printf("%d\n",x);delTNode(tree,1);inOrder(tree);return 0;
}

 五、折半查找OJ练习

读取10个元素 87  7 60 80 59 34 86 99 21  3,然后建立二叉查找树,
中序遍历输出3  7 21 34 59 60 80 86 87 99,
针对有序后的元素,存入一个长度为10的数组中,通过折半查找找到21的下标(下标为2),
然后输出2
//折半查找
int getPosition(ElementType A[],ElementType x,int low,int high){if (low>=high){return -1;}int mid=(low+high)/2;if (A[mid]==x){return mid;}if (x>A[mid]){return getPosition(A,x,mid+1,high);} else{return getPosition(A,x,low,mid-1);}
}

完整代码 

#include <stdio.h>
#include <stdlib.h>/*** 读取10个元素 87  7 60 80 59 34 86 99 21  3,然后建立二叉查找树,* 中序遍历输出3  7 21 34 59 60 80 86 87 99,* 针对有序后的元素,存入一个长度为10的数组中,通过折半查找找到21的下标(下标为2),然后输出2*/typedef int ElementType;typedef struct BSTNode{ElementType data;BSTNode *rchild;BSTNode *lchild;
}BSTNode,*BSTree;/*** 构造二叉排序树* @param tree* @param x*/
void buildTree(BSTree &tree,ElementType &x){if (tree==NULL){tree=(BSTree) calloc(1, sizeof(BSTNode));tree->data=x;//注意return;}if (x>tree->data){buildTree(tree->rchild,x);}if (x<tree->data){buildTree(tree->lchild,x);}if (x==tree->data){return;}
}//查找
int getPosition(BSTree &tree,int postion,ElementType x){if (tree!=NULL&&x==tree->data){return tree->data;}if (x>tree->data){return getPosition(tree->rchild,0,x);} else{return getPosition(tree->lchild,0,x);}
}//删除节点
void delTNode(BSTree &tree,ElementType x){if (tree==NULL){return;}BSTNode *temp=tree;if (x>temp->data){delTNode(tree->rchild,x);}if (x<temp->data){delTNode(tree->lchild,x);}if (x==temp->data){if (temp->lchild==NULL&&temp->rchild!=NULL){//注意记得改变此时被删除的位置的地址tree=temp->rchild;free(temp);}if (temp->rchild==NULL&&temp->lchild!=NULL){//注意记得改变此时被删除的位置的地址tree=temp->lchild;free(temp);}if (temp->lchild==NULL&&temp->rchild==NULL){//注意记得改变此时被删除的位置的地址tree=NULL;free(temp);}if (temp->lchild!=NULL&&temp->rchild!=NULL){//左右子树都不为空//找左子树的左右边//或者找右子树的最左边来代替temp=temp->lchild;while (temp->rchild!=NULL){temp=temp->rchild;}tree->data=temp->data;//因为这时候有俩个一样的值了 我们要确认我们要删除的是哪个值//因此这里应该删除这个节点的左子树上那个替死鬼delTNode(tree->lchild,temp->data);}}
}//中序遍历 对于二叉排序树来说中序遍历就是从小到大依次排序
void inOrder(BSTree tree){if (tree==NULL){return;}inOrder(tree->lchild);printf("%3d",tree->data);inOrder(tree->rchild);
}int i=0;//中序遍历 对于二叉排序树来说中序遍历就是从小到大依次排序
void inOrderI(BSTree tree,ElementType A[]){if (tree==NULL){return;}inOrderI(tree->lchild,A);A[i++]=tree->data;printf("%3d",tree->data);inOrderI(tree->rchild,A);
}//折半查找
int getPosition(ElementType A[],ElementType x,int low,int high){if (low>=high){return -1;}int mid=(low+high)/2;if (A[mid]==x){return mid;}if (x>A[mid]){return getPosition(A,x,mid+1,high);} else{return getPosition(A,x,low,mid-1);}
}int main() {BSTree tree;//注意tree=(BSTree) calloc(1, sizeof(BSTNode));ElementType x;scanf("%d",&x);tree->data=x;for (int i = 1; i <= 9; ++i) {scanf("%d",&x);buildTree(tree,x);}ElementType A[10];inOrderI(tree,A);printf("\n");int position=getPosition(A,21,0,9);printf("%d\n", position);return 0;
}

 

六、折半查找 (真题)中位数应用

注意最后是s / d  的位置的值

注意移动的时候数组长度是变化的 

1. 判断哪个中位数小  

保证消掉的元素个数是相等的

奇数个长度  消掉小的前面的所有元素  大的后面的所有元素

偶数个长度  消掉小的前面的所有元素及其它本身  大的后面的所有元素

2.退出循环的条件是 s1!=d1|| s2!=d2 --直到俩个数组中就s1d1都指向一个元素  s2d2同理

 

 

#include <stdio.h>void NarrowScope(int n, int m1, int m2, int &s2, int &d1);//不合并查找中位数--去掉数  --就是移动下标
int getMidA_B(int A[],int B[],int n){//分别为 A B的 首尾 中位数  所在下标位置int s1,s2,d1,d2,m1,m2;s1=s2=0;d1=d2=n-1;m1=(s1+d1)/2;m2=(s2+d2)/2;if (A[m1]==B[m2]){return A[m1];}//去掉小哪个中位数之前的数    注意分奇偶//去掉大的那个中位数之后的数  注意分奇偶//循环判断哪个中位数大--缩小范围--直到俩个数组中都只剩下一个数s1=d1 s2=d2时 小的那个即为中位数while (s1!=d1||s2!=d2){m1=(s1+d1)/2;m2=(s2+d2)/2;if (A[m1]==B[m2]){return A[m1];}if (A[m1]>B[m2]){if ((s1+d1)%2==0){//奇数个//去掉大的之后的所有数d1=m1;//去掉小的之前的所有数s2=m2;} else{//偶数个//去掉大的 之后的所有数d1=m1;//去掉小的 中位数及之前的所有数s2=m2+1;}}if (A[m1]<B[m2]){if ((s1+d1)%2==0){//奇数个//去掉大的之后的所有数d2=m2;//去掉小的之前的所有数s1=m1;} else{//偶数个//去掉大的 之后的所有数d2=m2;//去掉小的 中位数及之前的所有数s1=m1+1;}}}//注意这里 要的是s /  d  而不是m  因为最终s 与d会重合return A[s1]>B[s2]?B[s2]:A[s1];
}int main() {int A[]={11,13,15,17,19};int B[]={2,4,6,8,20};int n=5;int mid=getMidA_B(A,B,n);printf("%d\n",mid);return 0;
}

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/522649.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法集训】基础算法:递推 | 概念篇

前言 递推最通俗的理解就是数列&#xff0c;递推和数列的关系就好比 算法 和 数据结构 的关系&#xff0c;数列有点像数据结构中的顺序表&#xff0c;而递推就是一个循环或者迭代的枚举过程。 递推本质上是数学问题&#xff0c;所以有同学问算法是不是需要数学非常好&#xff…

【考研数学】李林《880》vs 李永乐《660》完美使用搭配

没有说谁一定好&#xff0c;只有适不适合自身情况&#xff0c;针对自身弱点选择性价比才最高。 两者侧重点不同&#xff0c;660适合强化前期&#xff0c;弥补基础的不足&#xff0c;880适合强化后期&#xff0c;题型全面&#xff0c;提高我们对综合运用知识的能力。 选择习题…

B端系统优化,可不是换个颜色和图标,看看与大厂系统的差距。

Hi&#xff0c;我是贝格前端工场&#xff0c;优化升级各类管理系统的界面和体验&#xff0c;是我们核心业务之一&#xff0c;欢迎老铁们评论点赞互动&#xff0c;有需求可以私信我们 一、不要被流于表面的需求描述迷惑。 很多人找我们优化系统界面&#xff0c;对需求总是轻描淡…

7-4 哲哲打游戏(Python)

哲哲是一位硬核游戏玩家。最近一款名叫《达诺达诺》的新游戏刚刚上市&#xff0c;哲哲自然要快速攻略游戏&#xff0c;守护硬核游戏玩家的一切&#xff01; 为简化模型&#xff0c;我们不妨假设游戏有 N 个剧情点&#xff0c;通过游戏里不同的操作或选择可以从某个剧情点去往另…

软件功能鉴定

软件鉴定 &#xff0c;软件功能鉴定&#xff0c;软件质量鉴定 软件产品质量鉴定&#xff1a;对于各种APP&#xff0c;软件&#xff0c;系统进行鉴定。

【PCIe】TLP结构与配置空间

&#x1f525;博客主页&#xff1a;PannLZ 文章目录 PCIe TLP结构PCIe配置空间和地址空间 PCIe TLP结构 TLP 主要由3个部分组成&#xff1a; Header 、 数据(可选&#xff0c;取决于具体的TLP 类 型 ) 和 ECRC (End to End CRC, 可选)。TLP 都始于发送端的事务层&#xff0c;终…

乐得瑞的一拖二100W智能分配方案更加成熟

在快节奏的现代生活中&#xff0c;手机不仅是通讯工具&#xff0c;更是我们工作、学习和娱乐的得力助手。然而&#xff0c;手机的电量问题一直是困扰我们的难题。为了解决这一问题&#xff0c;市场上应运而生了一种名为“一拖二快充线”的充电设备。它集快速充电与独特设计于一…

基于STM32的展馆火灾监控系统的设计与实现

自从人类学会用火后&#xff0c;火灾就开始伴随人类了&#xff0c;几千年来火灾对人类造成的损失不可谓不大&#xff0c;但究其原因&#xff0c;除了人为纵火、放火之外&#xff0c;其他火灾都是在人们没有注意或没有检测到才产生的&#xff0c;所以防火的重要方面仍是防患于未…

蓝桥杯每日一题:烤鸡dfs

这道题考察了dfs的应用&#xff0c;题干十分有趣&#xff0c;思考过程对以后类似题目也有很强的参考性&#xff0c;一起来学习吧&#xff01; 题目&#xff1a; # 烤鸡 ## 题目背景 猪猪 Hanke 得到了一只鸡。 ## 题目描述 猪猪 Hanke 特别喜欢吃烤鸡&#xff08;本是同畜…

本鲸多方位助力创业者高效对接创新创业机遇

在科技创新的浪潮中&#xff0c;创业者们不断探索着新的商业机会&#xff0c;寻求着创新创业的道路。然而&#xff0c;面对复杂多变的市场环境和激烈的竞争压力&#xff0c;如何高效对接创新创业机遇成为了摆在创业者面前的重要课题。 本鲸依托海南本鲸投资有限公司和重庆本鲸…

Leetcode - 周赛387

目录 一&#xff0c;3069. 将元素分配到两个数组中 I 二&#xff0c;3070. 元素和小于等于 k 的子矩阵的数目 三&#xff0c;3071. 在矩阵上写出字母 Y 所需的最少操作次数 四&#xff0c;3072. 将元素分配到两个数组中 II 一&#xff0c;3069. 将元素分配到两个数组中 I 本…

给一篇word注音可不可以只要拼音不要汉字 word中如何只保留拼音不要汉字

word中如何只保留拼音不要汉字&#xff0c;如果你想要只保留拼音而去除汉字&#xff0c;可以通过一系列步骤来实现。以下是一个详细的教程&#xff0c;帮助你完成这个任务。 首先&#xff0c;确保你的电脑已经安装了“汇帮注音大师”软件。如果没有&#xff0c;你需要安装一下…