基于二叉排序树的基本操作
来源:互联网 发布:qq三国79js单刷孟获 编辑:程序博客网 时间:2024/06/07 23:44
二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根节点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
以下为二叉排序树的实例和结点结构
1、找出被插结点的父亲结点。
以下为二叉排序树的实例和结点结构
//二叉排序树的结点结构typedef struct Node{ ElemType val; struct Node *LChild,*RChild;}Node;二叉排序树的插入
1、找出被插结点的父亲结点。
2、判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入。
3、若二叉树为空。则首先单独生成根结点。
1、若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则可以直接删除此子结点。
2、若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉排序树的特性。
3、若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)-即让*f的左子树(如果有的话)成为*p左子树的最左下结点(如果有的话),再让*f成为*p的左右结点的父结点。
以下为完整程序
//在二叉排序树中插入一个关键字为value的结点int Insert(Node *root,int value){ Node *p=root,*q=NULL,*par=NULL; int mark=0; while(p!=NULL&&mark==0){//找到value应插入的父节点 par=p; if(p->val==value){ mark=1; }else if(p->val>value){ p=p->LChild; }else if(p->val<value){ p=p->RChild; } } if(mark==1) return 0;//存在value则不插入 q=(Node *)malloc(sizeof(Node)); q->val=value; q->LChild=q->RChild=NULL; if(root==NULL){ root=q; }else if(par->val>q->val){//判断插入其左右子树 par->LChild=q; }else{ par->RChild=q; } return 1;}二叉排序树的查找,像其他树的查找一样遍历结点
//查找关键字为key的结点,返回指向该结点的指针Node *Search(Node *root,int key){ Node *p=NULL; if(root==NULL){ return NULL; } p=root; while(p){ if(p->val==key){ return p; }else if(p->val>key){//当前节点的值大于key则去结点的左子树查找 p=p->LChild; }else{ p=p->RChild; } } return p;}二叉排序树的删除
1、若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则可以直接删除此子结点。
2、若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉排序树的特性。
3、若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)-即让*f的左子树(如果有的话)成为*p左子树的最左下结点(如果有的话),再让*f成为*p的左右结点的父结点。
//从二叉排序树中删除值为value的结点并重新连接它的左或右子树int Delete(Node *root,int value){ Node *s,*p,*q; p=Search(root,value);//查找value的结点 if(p==NULL) return 1;//没有找到 if(!p->RChild){//右子树空则只需重接它的左子树 q=p; p=p->LChild; free(p); }else if(!p->LChild){//左子树空则只需重接它的右子树 q=p; p=p->RChild; free(p); }else{//左右子树均不空 q=p; s=p->RChild; while(s->LChild){//转右,然后向左到尽头 q=s; s=s->LChild; } p->val=s->val;//s指向被删结点的前驱 if(q!=p){ q->LChild=s->RChild; }else{ q->LChild=s->LChild; } free(s); } return 0;}
以下为完整程序
#include<stdio.h>#define N 100typedef int ElemType;//二叉排序树的结点结构typedef struct Node{ ElemType val; struct Node *LChild,*RChild;}Node;Node *BitRepTr;//查找关键字为key的结点,返回指向该结点的指针Node *Search(Node *root,int key){ Node *p=NULL; if(root==NULL){ return NULL; } p=root; while(p){ if(p->val==key){ return p; }else if(p->val>key){//当前节点的值大于key则去结点的左子树查找 p=p->LChild; }else{ p=p->RChild; } } return p;}//在二叉排序树中插入一个关键字为value的结点int Insert(Node *root,int value){ Node *p=root,*q=NULL,*par=NULL; int mark=0; while(p!=NULL&&mark==0){//找到value应插入的父节点 par=p; if(p->val==value){ mark=1; }else if(p->val>value){ p=p->LChild; }else if(p->val<value){ p=p->RChild; } } if(mark==1) return 0;//存在value则不插入 q=(Node *)malloc(sizeof(Node)); q->val=value; q->LChild=q->RChild=NULL; if(root==NULL){ root=q; }else if(par->val>q->val){//判断插入其左右子树 par->LChild=q; }else{ par->RChild=q; } return 1;}//从二叉排序树中删除值为value的结点并重新连接它的左或右子树int Delete(Node *root,int value){ Node *s,*p,*q; p=Search(root,value);//查找value的结点 if(p==NULL) return 1;//没有找到 if(!p->RChild){//右子树空则只需重接它的左子树 q=p; p=p->LChild; free(p); }else if(!p->LChild){//左子树空则只需重接它的右子树 q=p; p=p->RChild; free(p); }else{//左右子树均不空 q=p; s=p->RChild; while(s->LChild){//转右,然后向左到尽头 q=s; s=s->LChild; } p->val=s->val;//s指向被删结点的前驱 if(q!=p){ q->LChild=s->RChild; }else{ q->LChild=s->LChild; } free(s); } return 0;}//中序遍历二叉排序树void MidOrder(Node *root){ if(root!=NULL){ MidOrder(root->LChild); printf("%d ",root->val); MidOrder(root->RChild); }}int main(){ Node *root,*p; int k,i,val,n,num[N]; printf("首先建立二叉排序树\n"); printf("请输入结点个数\n"); scanf("%d",&n); if(n<1){ return -1; } root=(Node *)malloc(sizeof(Node)); printf("输入各节点的关键字值,以空格间隔\n"); scanf("%d",&num[0]); root->val=num[0]; root->LChild=NULL; root->RChild=NULL; for(i=1;i<n;i++){ scanf("%d",&num[i]); Insert(root,num[i]); } printf("对二叉排序树进行的中序遍历结果如下:\n"); MidOrder(root); printf("\n"); printf(" 1-----------查找\n"); printf(" 2-----------查找\n"); printf(" 3-----------查找\n"); printf("请选择(1-3):"); scanf("%d",&k); switch(k){ case 1: printf("选择了查找\n"); printf("请输入要查找的值:"); scanf("%d",&val); if(Search(root,val)!=NULL){ printf("找到了\n"); }else{ printf("没有找到\n"); } break; case 2: printf("选择了插入\n"); printf("请输入要插入的值:"); scanf("%d",&val); if(Insert(root,val)!=0){ printf("插入成功\n"); printf("对新二叉排序树进行中序遍历的结果如下:\n"); MidOrder(root); printf("\n"); }else{ printf("插入失败,值为%d的结点已存在\n",val); } break; case 3: printf("选择了删除\n"); printf("请输入要删除的值:"); scanf("%d",&val); if(Delete(root,val)!=1){ printf("删除成功\n"); printf("对新二叉排序树进行中序遍历的结果如下:\n"); MidOrder(root); printf("\n"); }else{ printf("删除失败,值为%d的结点不存在\n",val); } break; default: printf(" 1-----------查找\n"); printf(" 2-----------查找\n"); printf(" 3-----------查找\n"); break; }}
0 0
- 基于二叉排序树的基本操作
- 二叉排序树的基本操作
- 二叉排序树的基本操作
- 二叉排序树的基本操作
- 二叉排序树的基本操作
- 二叉排序树的基本操作
- 二叉排序树的基本操作
- 二叉排序树的基本操作
- 二叉排序树的基本操作测试
- 二叉排序树的基本操作(完整代码)
- 数据结构之二叉排序树(基于指针实现基本操作)
- 数据结构之二叉排序树(基于引用实现基本操作)
- 二叉排序树基本操作详解
- *二叉排序树基本操作*
- C++ 二叉排序树基本操作1
- 二叉排序树(二叉查找树)的基本操作
- 数据结构课设--6二叉排序树的基本操作
- 数据结构——二叉排序树的基本操作(BST)
- go语言方法Value Receiver, Pointer Receiver
- 自动化读取文件真的好吗?
- 函数返回类的引用
- python操作mysql
- centos环境配置信息
- 基于二叉排序树的基本操作
- java中文汉字按英文字母表排序
- DTW的基本原理及其C语言实现
- STL vector的内部实现原理及基本用法
- 欢迎使用CSDN-markdown编辑器
- 微信小程序开发之弹出菜单
- mongoDB
- [XOR最小生成树 分治 Trie || Prim 堆] BNUOJ 52318 Be Friends
- The method getTextContent() is undefined for the type Node解决方法(eclipse)