二叉排序树
2015-12-13 21:17
381 查看
特点:
1)左子树非空则左子树所有节点的值小于根节点
2)右子树非空则右子树所有节点的值大于根节点
3)左右子树都为二叉排序树
查找次数等于树高,最坏情况为o(n),最好为o(log n)
以中序遍历输出则为有序序列,也可以称为树排序,排序复杂度o(n*log n)
1)左子树非空则左子树所有节点的值小于根节点
2)右子树非空则右子树所有节点的值大于根节点
3)左右子树都为二叉排序树
查找次数等于树高,最坏情况为o(n),最好为o(log n)
以中序遍历输出则为有序序列,也可以称为树排序,排序复杂度o(n*log n)
# include<iostream> #include<cstdio> #include<cstdlib> using namespace std; typedef int datatype; struct bsnode { datatype data; bsnode *l,*r; bsnode(){l=r=NULL;} }; bsnode* Insert(bsnode *t,datatype x) { bsnode *p=t,*f=NULL;//f为表示下一个点的父节点 while(p) { if(p->data==x) return t ; //若该值已在树中出现,就不必再插入 f=p; if(x<p->data) p=p->l; //比根小就往左边走 else p=p->r;//否则往右边 } p=new bsnode(); p->data=x; if(f==NULL) return p; if(x<f->data) f->l=p; else f->r=p; return t; } bsnode *create() //建立二叉排序树 { datatype x; bsnode *root=NULL; cin>>x; while(x!=-1) { root=Insert(root,x); cin>>x; } return root; } void inorder(bsnode *t) //中序遍历输出 { if(t==NULL) return ; inorder(t->l); cout<<t->data<<' '; inorder(t->r); } bsnode * FindX(bsnode *t,datatype x) //递归查找值为x节点 { if(t==NULL||t->data==x) return t; if(x<t->data) return FindX(t->l,x); return FindX(t->r,x); } void FindXbyloop(bsnode *t,bsnode **f,bsnode **p,datatype x) //非递归查找值x的节点和x父节点 { *p=t; *f=NULL; while(*p) { if((*p) -> data==x) return ; *f=*p; if(x<(*p)->data) *p=(*p)->l; else *p = (*p)->r; } } bsnode *DeleteX(bsnode *t,datatype x) //二叉排序树删除节点 { bsnode *p,*orderpre,*f,*q; FindXbyloop(t,&f,&p,x);//找到待删除的节点和父亲 q=p;//保存待删点 if(p==NULL) return t; if(p->l==NULL&&p->r==NULL) //删除的为叶子节点 { if(f==NULL) t=NULL; //若只有根节点,返回空树 else if(f->l->data==x) f->l=NULL; // 若左儿子等于x,父节点左儿子指向为空 else f->r=NULL; //否则右儿子为空 free(q); } else if(p->l==NULL) //删除一度节点且删除节点左儿子为空 { if(f==NULL) t=p->r; //若该节点为根,左儿子右儿子作为根 else if(f->l->data==x) f->l=p->r; // 节点位于中间,父节点的左儿子为删除节点,使父节点左儿子指向删除节点的右儿子 else f->r=p->r; //父节点的右儿子指向删除节点的右儿子 free(q); } else if(p->r==NULL) //删除一度节点且右儿子为空 { if(f==NULL) t=p->l; else if(f->l->data==x) f->l=p->l; else f->r=p->l; free(q); } else //删除二度节点(把删除节点右子树的前趋替换删除节点) { orderpre = p->r; while(orderpre->l) orderpre=orderpre->l;//找到右子树的前趋 orderpre->l=p->l;//使得删除节点的左子树作为右子树前趋节点的左左子树 if(f==NULL) t=p->r; //如果被删除的是根,被删除节点的右儿子作为根 else if(f->l->data==x) f->l=p->r; //节点处于中间,父节点的左儿子为删树节点,则把删除节点的右儿子作为父节点的左儿子 else f->r=p->r; free(q); } return t; } int main() { datatype x; int n = 5; bsnode *root,*p,*f; root=create(); inorder(root); cout<<endl; /* cin>>x; p=FindX(root,x); if(p) cout<<p->data<<endl; else cout<<"不存在"<<endl;*/ /* FindXbyloop(root,&f,&p,x); if(p!=NULL) cout<<f->data<<" "<<p->data<<endl;*/ while(n) { cin>>x; root=DeleteX(root,x); inorder(root); cout<<endl; } return 0; }
相关文章推荐
- 创建SSH Key连接github或gitlab
- android:gravity 和 android:layout_gravity 区别
- 创建SSH Key连接github或gitlab
- c语言总结
- 文字检测
- nova http 409 虚拟机状态重置
- [javase学习笔记]-4.4 函数的重载
- 申请内存的函数有哪些
- Q:应用程序无法正常启动(0xc000007b)
- 使用Windows Live发布博客到博客园
- 操作系统---基础题目汇总十三
- TCP/IP详解卷1 读书笔记:第二十八章 SMTP和POP3协议
- vmalloc 实现
- 源码安装zabbix2.4
- 内核空间与用户空间的通信方式
- SMO(Sequential Minimal Optimization) 伪代码(注释)
- 1-1、Spark 的local模式安装
- poj_1019
- JgibbLDA输出结果说明与示例
- POJ 2449Remmarguts' Date K短路模板 SPFA+A*