新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正
1. 二叉排序树的定义
它或者是一棵空树;或者是拥有下列性子的二叉树:
(1)若左子树不空,则左子树上全部结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上全部结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
2. java实现代码(注:以下代码参考网上优良代码,均已编写实现)
试试看——不是像企鹅那样静静的站在海边,翘首企盼机会的来临,而是如苍鹰一般不停的翻飞盘旋,执著的寻求。 试试看——不是面对峰回路转、杂草丛生的前途枉自嗟叹,而是披荆斩棘,举步探索。 试试看——不是拘泥于命运的禁锢,听凭命运的摆布,而是奋力敲击其神秘的门扉,使之洞开一个新的天地。微笑着,去唱生活的歌谣。
/*
* 注:该代码实现了二叉查找树的全部操作:包括,插入、删除、查找、排序输出、前驱、后继等。
* */
import java.util.ArrayList;
import java.util.List;
public class BinarySearchTree {
// 二叉查找树的根节点
private TreeNode root = null ;
private List<TreeNode> nodelist = new ArrayList<TreeNode>();
// 二叉树的节点类
private class TreeNode{
private int key ;
private TreeNode leftChild ;
private TreeNode rightChild ;
private TreeNode parent ;
// 构造器
public TreeNode(int key , TreeNode leftChild , TreeNode rightChild , TreeNode parent)
{
this.key = key ;
this.leftChild = leftChild ;
this.rightChild = rightChild ;
this.parent = parent ;
}
public int getKey()
{
return key ;
}
public String toString()
{
String leftkey = (leftChild == null ? "" : String.valueOf(leftChild.key));
String rightkey = (rightChild == null ? "" : String.valueOf(rightChild.key));
return "("+leftkey+","+key+","+rightkey+")";
}
}
/*
* 判断二叉查找树是不是为空;若为空,返回true,否则返回false
* */
public boolean isEmpty()
{
if(root == null){
return true ;
}else{
return false ;
}
}
/*
* 对于某些二叉查找树操作(比如删除关键字)来说,若树为空,则抛出异常。
* */
public void TreeEmpty() throws Exception
{
if(isEmpty()){
throw new Exception("树为空!");
}
}
/*
* 在二叉查找树中查询给定关键字的节点
* */
public TreeNode search(int key)
{
TreeNode pNode = root ;
while(pNode!=null && pNode.key !=key)
{
if(key<pNode.key){
pNode = pNode.leftChild;
}else{
pNode = pNode.rightChild;
}
}
return pNode ;
}
/*
* 获得二叉查找树中的最小关键字节点
* */
public TreeNode minTreeNode(TreeNode node)throws Exception{
if(node == null)
throw new Exception("树为空!");
TreeNode pNode = node ;
while(pNode.leftChild!=null)
{
pNode = pNode.leftChild ;
}
return pNode ;
}
/*
* 获得二叉查找树中的最大关键字的节点
* */
public TreeNode maxTreeNode(TreeNode node)throws Exception{
if(node == null)
throw new Exception("树为空!");
TreeNode pNode = node ;
while(pNode.rightChild!=null)
{
pNode = pNode.rightChild ;
}
return pNode ;
}
/*
* 查找给定节点在中序遍历下的后继节点
* */
public TreeNode successor(TreeNode node)throws Exception{
if(node == null)
return null ;
// 若该节点的右子树不为空,则它的后继节点为右子树中的最小关键字节点
if(node.rightChild!=null){
return minTreeNode(node.rightChild);
}
// 右子树为空的情况
TreeNode pNode = node.parent ;
while(pNode!=null && node == pNode.rightChild){
node = pNode ;
pNode = pNode.parent;
}
return pNode ;
}
/*
* 查找给定节点在中序遍历下的前驱节点
* */
public TreeNode precursor(TreeNode node)throws Exception{
if(node == null)
return null;
// 若节点的左子树不为空,则它的前驱节点就是左子树中的最大节点
if(node.leftChild!=null){
return maxTreeNode(node.leftChild);
}
// 左子树为空的情况
TreeNode pNode = node.parent ;
while(pNode!=null&&node==pNode.leftChild){
node = pNode ;
pNode = pNode.parent;
}
return pNode ;
}
/*
* 将给定的关键字插入到二叉查找树中
* */
public void insert(int key){
TreeNode node = null ;
TreeNode newNode = new TreeNode(key,null,null,null);
TreeNode pNode = root ;
if(root==null){
root = newNode ;
return ;
}
while(pNode!=null){
node = pNode ;
if(key<pNode.key){
pNode = pNode.leftChild ;
}else if(key > pNode.key){
pNode = pNode.rightChild;
}else{ // 树中已存在给定的关键字节点了
return ;
}
}
if(key<node.key){
node.leftChild = newNode ;
newNode.parent = node ;
}else{
node.rightChild = newNode ;
newNode.parent = node ;
}
}
/*
* 从二叉查找树中删除给定的节点
* */
public void delete(int key)throws Exception{
TreeNode pNode = search(key);
if(pNode == null){
throw new Exception("树中不存在要删除的关键字!");
}
delete(pNode);
}
private void delete(TreeNode pNode)throws Exception{
if(pNode.leftChild ==null && pNode.rightChild ==null){// 第一种情况:要删除的节点既无左孩子,又无右孩子
TreeNode parentNode = pNode.parent ;
if(pNode == parentNode.leftChild){
parentNode.leftChild = null ;
}else{
parentNode.rightChild = null ;
}
return ;
}
if(pNode.leftChild == null && pNode.rightChild != null){// 第二种情况:要删除节点的左子树为空,右子树不为空
TreeNode parentNode = pNode.parent ;
if(pNode == parentNode.leftChild){
parentNode.leftChild = pNode.rightChild;
pNode.rightChild.parent = parentNode;
}else{
parentNode.rightChild = pNode.rightChild;
pNode.rightChild.parent = parentNode;
}
return ;
}
if(pNode.leftChild !=null && pNode.rightChild ==null){// 第三种情况,要删除节点的左子树不为空,右子树为空
TreeNode parentNode = pNode.parent ;
if(pNode == parentNode.leftChild){
parentNode.leftChild = pNode.leftChild ;
pNode.leftChild.parent = parentNode;
}else{
parentNode.rightChild = pNode.leftChild;
pNode.leftChild.parent = parentNode;
}
return ;
}
// 第四种情况,要删除节点的左右子树都不为空,则删除该节点的后继,并用该结点的后继代替该结点
TreeNode successorNode = successor(pNode);
delete(successorNode);
pNode.key = successorNode.key;
}
/*
* 获得二叉查找树中中序遍历的【节点】列表
* */
public List<TreeNode> inorderTraverseList(){
if(nodelist!=null){
nodelist.clear();
}
inorderTraverse(root);
return nodelist;
}
public void inorderTraverse(TreeNode root){
if(root!=null){
inorderTraverse(root.leftChild);
nodelist.add(root);
inorderTraverse(root.rightChild);
}
}
/*
* 获得二叉查找树中中序遍历的【关键字】列表
* */
public String toStringOfOrderList(){
StringBuilder sBuilder = new StringBuilder("[");
for(TreeNode p : inorderTraverseList()){
sBuilder.append(p.key);
sBuilder.append(" ");
}
sBuilder.append("]");
return sBuilder.toString();
}
/*
* 获得二叉查找树的字符串表示
* */
public String toString()
{
StringBuilder sBuilder = new StringBuilder("[");
for(TreeNode p : inorderTraverseList()){
sBuilder.append(p); // 注:这里是和上面的区分
sBuilder.append(" ");
}
sBuilder.append("]");
return sBuilder.toString();
}
public TreeNode getRoot()
{
return root ;
}
public static void testNode(BinarySearchTree bst , TreeNode pNode)throws Exception
{
System.out.println("本结点: " + pNode);
System.out.println("前趋结点: " + bst.precursor(pNode));
System.out.println("后继结点: " + bst.successor(pNode));
}
public static void testTraverse(BinarySearchTree bst) {
System.out.println("二叉树遍历:" + bst);
System.out.println("二叉查找树转换为有序列表: " + bst.toStringOfOrderList());
}
public static void main(String[] args)
{
try{
int delkey = 15 ;
BinarySearchTree bst = new BinarySearchTree();
System.out.println("二叉查找树是不是为空?"+(bst.isEmpty()?"是":"否"));
int[] keys = new int[]{15,6,18,3,7,13,20,2,9,4};
for(int key : keys){
bst.insert(key);
}
System.out.println("二叉查找树是不是为空?"+(bst.isEmpty()?"是":"否"));
TreeNode minkeyNode = bst.minTreeNode(bst.getRoot());
System.out.println("最小关键字:"+minkeyNode.getKey());
testNode(bst,minkeyNode);
TreeNode maxKeyNode = bst.maxTreeNode(bst.getRoot());
System.out.println("最大关键字: " + maxKeyNode.getKey());
testNode(bst, maxKeyNode);
System.out.println("根结点关键字: " + bst.getRoot().getKey());
testNode(bst, bst.getRoot());
testTraverse(bst);
System.out.println("删除关键字6后的二叉查找树:");
bst.delete(delkey);
System.out.println("删除根节点后的根节点:"+bst.getRoot().getKey());
testNode(bst,bst.getRoot());
testTraverse(bst);
System.out.println("****************************** ");
}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
3. 代码运行结果:
保持天天的学习,加油!!!
文章结束给大家分享下程序员的一些笑话语录: 一条狗在街上闲逛,看见橱窗里一张告示:「招聘程序员。会编程,有团队精神,至少精通两种语言。均等机会。」
那条狗就进去申请,但是被拒绝了。
「我不能雇一条狗在公司里做事。」经理说。
狗不服气,指着告示上「均等机会」几字抗议。
经理没法,叹了口气,不屑地问道:「你会编程吗?」
那条狗默默地走到电脑前,编了个程序,运作准确。
「你有团队精神吗?」经理问。
那条狗掉头看了看门外,一大群野狗在外面虎视耽耽。
「我真的不能雇狗做这份工作。」经理气急败坏地说。
「就算会编程、有团队精神,但是我需要的雇员至少要能精通两种语言。」
那条狗抬头看着经理说:「喵-噢。」
--------------------------------- 原创文章 By
节点和node
---------------------------------