二叉排序树:删除操作
2016-03-21 18:46
357 查看
删除分为两种可能:
1.只有左子树,或右子树,或叶结点。
View Code
先将s移到待删节点的前驱,方法是:先左转,再一直右转。如图所示,s左转,然后接着右转,结果右转直接为空。此时的状态是:p=q; s=p->left。
另一种情况,右树不为空,一直往前移动,这个时候的规律是:p总指向s的父结点。操作如下:
删除的五种可能样式:
1.只有左子树,或右子树,或叶结点。
int Delete(Tree &p) { Tree q,s; if(p->right==NULL)/*只有左子树*/ { q=p; p=p->left; free(q); } else if(p->left==NULL)/*只有右子树*/ { q=p; p=p->right; free(q); } else { q=p; s=p->left; while(s->right) { q=s; s=s->right; } p->data=s->data; if(q!=p) { q->right=s->left; } else q->left=s->left; free(s); } return TRUE; } int DeleteBSF(Tree &T,int key) { if(!T) return FALSE; else { if(key==T->data) return Delete(T); else if(key<T->data) return DeleteBSF(T->left,key); else return DeleteBSF(T->right,key); } }
View Code
先将s移到待删节点的前驱,方法是:先左转,再一直右转。如图所示,s左转,然后接着右转,结果右转直接为空。此时的状态是:p=q; s=p->left。
另一种情况,右树不为空,一直往前移动,这个时候的规律是:p总指向s的父结点。操作如下:
q->left=s->left; free(s);
删除的五种可能样式:
/*------二叉排序树的查找、插入操作------*/
#include <iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
typedef struct node
{
int data;
struct node *left,*right;
}*Tree,Node;
int Delete(Tree &p) { Tree q,s; if(p->right==NULL)/*只有左子树*/ { q=p; p=p->left; free(q); } else if(p->left==NULL)/*只有右子树*/ { q=p; p=p->right; free(q); } else { q=p; s=p->left; while(s->right) { q=s; s=s->right; } p->data=s->data; if(q!=p) { q->right=s->left; } else q->left=s->left; free(s); } return TRUE; } int DeleteBSF(Tree &T,int key) { if(!T) return FALSE; else { if(key==T->data) return Delete(T); else if(key<T->data) return DeleteBSF(T->left,key); else return DeleteBSF(T->right,key); } }
int Search(Tree &T,int key,Tree f,Tree &p)/*查找*/
{
if(!T)/*最后一步依然没有找到等于key的数据*/
{
p=f;/*f必定是叶子结点*/
return FALSE;
}
else if(key==T->data)
{
p=T;/*指向等于key的数据*/
cout<<"f->data="<<f->data<<endl;
return TRUE;
}
else if(key<T->data)
{
return Search(T->left,key,T,p);
}
else
return Search(T->right,key,T,p);
}
int Insert(Tree &T,int key,Tree &p)/*插入*/
{
Tree s;
if(!Search(T,key,NULL,p))/*如果没有key这个数据*/
{
s=(Tree)malloc(sizeof(Node));
s->data=key;
s->left=s->right=NULL;
if(!p)/*如果是棵空树*/
{
T=s;/*s就为根结点*/
}
else if(key<p->data)
{
p->left=s;
}
else if(key>p->data)
{
p->right=s;
}
return TRUE;
}
return FALSE;
}
void Traverse(Tree &T)/*遍历*/
{
if(T)
{
Traverse(T->left);
cout<<T->data<<" ";
Traverse(T->right);
}
}
int main()
{
Tree T=NULL,p;
int a[]={5,6,7,2,4,10};
for(int i=0;i<sizeof(a)/sizeof(a[0]);i++)
Insert(T,a[i],p);
Traverse(T);
DeleteBSF(T,4);
cout<<"删除结点后:"<<endl;
Traverse(T);
return 0;
}
相关文章推荐
- Http协议与TCP协议简单理解
- UVA 10341
- Android 开发过程遇到的错误和总结
- 3D dungeon
- 【Win 10 应用开发】UDP广播
- 面向过程写程序完全要不得
- 3D dungeon
- 给eclipse 安装spring ide插件
- c++11 学习及测试(auto,decltype,range for...)
- Activity与Fragment的生命周期详解
- python yield协程
- 数据库中的VARCHAR(M)及其他变长类型
- SVM支持向量机原理(一)
- Activity与Fragment的生命周期详解
- Android笔记——六大布局
- 学习C语言,在软件测试中如何用?
- 普元Js将页面输入框改为查看显示
- 专题一 · 1005
- 狐狸抓兔子(实验楼的练习)
- 有关小波变换的介绍