算法导论——(2)二叉查找树的实现
来源:互联网 发布:淘宝刷一个皇冠多少钱 编辑:程序博客网 时间:2024/06/05 17:28
正在学习算法导论,根据书上的伪代码和思想实现二叉查找树。
主要方法有:
1.查找最大关键字的结点
2.查找最小关键字的结点
3.查找特定关键字的结点
4.查找一个结点的后继结点(即按照中序遍历在该点后一个位置的点,这个点的键值是比该点键值大的最近的点)。
5.插入节点
6.删除结点
每个方法的思想:
1.查找最大关键值的点:
根据二叉查找树的性质,关键字最大的点在树的最右边
Entry TreeMaximum(Entry x) { if (x.right!= null) x = x.right; return x; }
2.同理,关键字最小的点在最左边
Entry TreeMinimum(Entry x) { if (x.left != null) x = x.left; return x; }
3.查找特定关键字的点
Entry TreeSearch(int key){ Entry x=root; while(x!=null&&x.key!=key){ if(x.key<key) x=x.right; else x=x.left; } //要么x==null,要么x.key=-key,x==null说明没找到 return x; }
4.查找一个节点的后继结点(即按照中序遍历在该点后一个位置的点,这个点的键值是比该点键值大的最近的点)。:
这里分两种情况,
1)当该节点的右孩子结点不为空时,我们可以确定比该键值大的最接近的节点一定在该节点的右子树上。并且是右子树的最小键值结点。
2)当该节点没有右孩子结点,那么它的后继节点一定是他的祖先,并且该节点处于后继结点的左子树上。那么找到最近的一个祖先结点y,y.left也是该节点的祖先(一个节点可以是自己的祖先)
Entry TreeSuccessor(Entry x) { if (x.right != null) { return TreeMinimum(x); } else { Entry y = x.p; while (y != null && x == y.right) { x = y; y = y.p; } return y; } }
5.插入节点,这个比较简单,一直比较找到一个合适的父节点就行了。然后挂在父节点的下面
void TreeInsert(Entry x) { Entry k = root; Entry y=null; while (k != null) { y=k; if (x.key < k.key) k = k.left; else k = k.right; } if(y!=null) if(x.key<y.key) y.left=x; else y.right=x; else root=x; x.p=y; }
6.删除结点,这个比较麻烦,分四种情况:
1)当该节点孤家寡人,没有子节点时,好办!直接把他的父节点的左(右)节点设置为null
2)当该节点只有一个孩子节点时,如果是只有左孩子,那么将该节点的父节点的左(或者右)孩子节点(看本身该节点处于其父节点的左还是右孩子节点)设置为该节点的左孩子节点;只有右孩子结点,相同的处理,将该节点的父节点的左(或者右)孩子节点(看本身该节点处于其父节点的左还是右孩子节点)设置为该节点的右孩子节点。
3)当该节点左孩子和右孩子都不为空时,我们要找到他的后继(前驱结点也行)结点y去替换掉当前的结点的位置,分两种情况:
<1>当后继结点y直接是该节点的右孩子,直接替换。把该节点的左子树挂到后继结点的左子树上
Transplant(x,y); y.left=x.left; y.left.p=y;
<2>当后继结点y不是该节点的右孩子而是右子树上的最小键值的一个节点,根据二叉查找树的性质该后继结点没有左子树(如果有左子树那它就不会是最小的键值结点了)。首先我们要把这个结点提取出来,用后继结点y的右孩子结点替换掉y的位置,再用y替换掉要删除的结点
if(y!=x.right){ Transplant(y,y.right); y.right=x.right; y.right.p=y; } Transplant(x,y); y.left=x.left; y.left.p=y;
替换函数为:
void Transplant(Entry u,Entry v){ if(u.p==null)//u为根节点 root=v; else if(u==u.p.left) u.p.left=v; else u.p.right=v; if(v!=null) v.p=u.p; }
好了到这里二叉查找树的基本函数都有了,遍历函数应该不用谢了,就是普通的二叉树遍历,下面是一个完整的二叉查找树实现例子
public class SearchTree { Entry root=null; public void print(){ InOrderTreeWalk(root); } void InOrderTreeWalk(Entry x){ if(x!=null){ InOrderTreeWalk(x.left); System.out.print(x.key+" "); InOrderTreeWalk(x.right); } } Entry TreeMinimum(Entry x) { if (x.left != null) x = x.left; return x; } Entry TreeSuccessor(Entry x) { if (x.right != null) { return TreeMinimum(x); } else { Entry y = x.p; while (y != null && x == y.right) { x = y; y = y.p; } return y; } } void TreeInsert(Entry x) { Entry k = root; Entry y=null; while (k != null) { y=k; if (x.key < k.key) k = k.left; else k = k.right; } if(y!=null) if(x.key<y.key) y.left=x; else y.right=x; else root=x; x.p=y; } void Transplant(Entry u,Entry v){ if(u.p==null) root=v; else if(u==u.p.left) u.p.left=v; else u.p.right=v; if(v!=null) v.p=u.p; } void TreeDelete(Entry x){ Entry p=x.p; if(x.left==null) Transplant(x,x.right); else if(x.right==null) Transplant(x,x.left); else{ Entry y=TreeMinimum(x.right); if(y!=x.right){ Transplant(y,y.right); y.right=x.right; y.right.p=y; } Transplant(x,y); y.left=x.left; y.left.p=y; } } Entry TreeSearch(int key){ Entry x=root; while(x!=null&&x.key!=key){ if(x.key<key) x=x.right; else x=x.left; } return x; } public static void main(String args[]){ SearchTree tree=new SearchTree(); tree.TreeInsert(new Entry(15)); tree.TreeInsert(new Entry(6)); tree.TreeInsert(new Entry(18)); tree.TreeInsert(new Entry(3)); tree.TreeInsert(new Entry(8)); tree.TreeInsert(new Entry(7)); tree.TreeInsert(new Entry(17)); tree.TreeInsert(new Entry(20)); tree.TreeInsert(new Entry(2)); tree.TreeInsert(new Entry(4)); tree.TreeInsert(new Entry(13)); tree.TreeInsert(new Entry(9)); tree.print(); System.out.println(); int key=8; Entry x=tree.TreeSearch(key); tree.TreeDelete(x); tree.print(); }}class Entry { int key; Entry left; Entry right; Entry p; public Entry(int key) { this.key = key; left = null; right = null; p = null; }}
- 算法导论——(2)二叉查找树的实现
- 《算法导论》二叉查找树的实现
- 算法导论——二叉查找树
- 算法导论——二叉查找树
- 算法导论第十二章——二叉查找树的C++代码实现
- 二叉查找数的实现(算法导论)
- 二叉查找树——删除操作(算法导论)
- 算法导论--二叉查找树--C++实现
- 【算法导论】二叉查找树的操作C++实现
- 算法导论上二叉查找树的实现java
- 《算法导论》12、二叉查找树(C++实现)
- 算法导论(八)二叉查找树
- 二叉查找树 (算法导论12)
- 二叉查找树(来自算法导论)
- 二叉查找树——算法导论第12章简易代码实现~
- 算法导论学习笔记——二叉查找树
- 《算法导论》— Chapter 12 二叉查找树
- 算法导论 二叉查找树
- halcon学习笔记——(3)HDevelop language(基本语句)
- HDOJ 1258 确定比赛名次 (拓扑排序)
- Hibernate(Oracle) 报Source not found错误原因一
- 第一次百度实习生电面
- EasyRTSPClient:基于live555封装的支持重连的RTSP客户端RTSPClient
- 算法导论——(2)二叉查找树的实现
- Linux Kernel Parameter config for Oracle
- android Service
- 1395 - Slim Span (最小生成树)
- Ignatius and the Princess I (hdu 1026 优先队列+bfs+输出路径)
- java was started but returned exit code=13
- Mac OS X安装redis-php扩展
- Python对xml的操作
- 【php】基于Redis的js、css缓存类