二叉排序树

来源:互联网 发布:软件外包行业发展趋势 编辑:程序博客网 时间:2024/04/29 21:23

二叉排序树是具有以下性质的二叉树:

1)如果左子树不为空,那么左子树的值均小于根节点的值,如果右子树不为空,那么右子树的值均大于根节点的值;

2)左右子树也分别是二叉排序树;

又称为二叉搜索树,二叉查找树。

二叉树的基本运算包括查找,插入和删除,其中以删除最难,这里就不介绍查找。

二叉树的插入:

需要认识到,二叉排序树插入的节点一定是作为叶子节点添加进去的;

//二叉排序树的插入public static Node InsertNode(Node t,KeyType k){Node f,p,s;//声明几个节点,s是新插入的点,p是s的双亲,f是p的双亲p = t;while(p){if(p.data == k){return t;System.out.println("存在k,不需要插入");}else{f = p;if(p.data<k) p = p.rchild;else p =p.lchild;}}//找到要插入的点的双亲ps = new Node(k);s.lchild=null;s.rchild=null;//新建节点if(t==null) t=s;else if(p.data<k) p.rchild = s;else p.lchild = s;//根据大小插入sreturn t;}


在二叉排序树中删除一个节点:

在二叉排序树中删除一个节点,首先要查找,如果没有这个点,查找失败,否则,根据下面的方法进行删除。
设待删除节点指针p,双亲节点为f,分三种情况:
1)p为叶子节点,那么删除此节点不会影响排序树的特性,直接删除,只需要把该节点的双亲节点相应位置置为null
2)p节点是单支节点,即p节点只有左子树Pl或者右子树Pr,此时只需要用Pl或Pr替代p的位置即可
3)p节点是双支节点,既有左子树,又有右子树,此时要按中序遍历保持排序树特性来进行删除,有两种方法:
1,用p的右子树pr代替以p为根的子树,即以pr为根的子树上升,再根据中序遍历序列(中序遍历保持不变),调整p的原左子树pl,
让他作为以pr为根的子树中序遍历时第一个节点的左子树(保证中序遍历是pl依然是在pr前面);
2,用p的直接直接后继(或直接前驱)代替p节点,这个节点只能是叶子或者单支节点(肯定存在),再按1)或2)删除p;
从上述的调整方案可以看到,按3)中的1方法,排序树的长度是可能会增加的,而按照2)方法排序数的高度肯定不会增加,
还有可能减小。
下面按2)方法实现一个节点的删除;

public static Node DeleteNode(Node <DataType> t,KeyType k)//在根节点为t的二叉排序树中删除元素为k的节点,并返回根节点{//声明几个节点,p是待删除节点,f是p的双亲节点,s是p的中序遍历中的直接后继节点,pre是s的双亲节点Node <DataType> f,s,p,r,pre;//先搜索待删节点p = t;while(p && p.data!=k){f = p;if(p.data<k)p = p.lchild;elsep = p.rchile;}if(p==null){System.out.println("不存在此节点,删除失败!");return t;}if(p.lchild && p.rchild){pre = p;s = p.rchild;while(s.lchild!=null){pre = s;s = s.lchild;}//查找到p点中序遍历的直接后继节点sp.data = s.data;  // s点取代待删p点r = s.rchild; // s的右子树上升(如果存在)if(pre == p)  pre.rchild = r;else  pre.lchild = r;}else  //情况1)和2) {if(p.lchild == null) r = p.lchild;else if(p.rchild == null) r = p.rchild;if(f == null){return t;//待删的是根节点}else if(f.lchild==p) f.lchild = r;else if(f.rchild==p) f.rchild ==r;}return t;}




0 0