35、二叉排序树的添加和删除节点

  • Post author:
  • Post category:其他


  • 思路:

二叉排序树的定义:形如图1所示,每棵二叉树有一个根节点,根节点下面至多有两个子节点,每个节点只能最多有两个分支节点,并且左侧分支子节点数值小于父节点数值,右侧子节点数值大于父节点数值。

图一

下面介绍了二叉排序树

的增加节点、删除节点(重点)、遍历

  • 增加节点

增加节点比较简单,直接上代码(如果增加的节点比当前节点值大,则遍历右侧子树,否则遍历左侧子树,直到遇到节点为空的时候,添加节点)

//添加节点
public void add(Node node) {
	if(node == null) {
		return;
	}
	if(node.getData() > this.getData()) {
		if(this.getRightNode() == null) {
			this.setRightNode(node);
		}else {
			this.getRightNode().add(node);
		}		
	}else {
		if(this.getLeftNode() == null) {
			this.setLeftNode(node);
		}else {
			this.getLeftNode().add(node);
		}
	}	
}
  • 删除节点

分为三种情况:

删除的节点是叶子节点最简单,直接找到父节点,让父节点的子树指向null即可;

删除的节点有一个子节点,也好办,直接让父节点指向删除节点的子节点即可;

删除节点有两个子节点,需要获得右子树节点中的最小值,用来填充删除的位置(原理自己想下,应该好理解),然后删除节点即可。

代码如图

//查找要删除的结点
public Node search(int value) {
	if(rootNode == null) {
		return null;
	} else {
		return rootNode.getDelNode(value);
	}
}

//查找父结点
public Node searchParent(int value) {
	if(rootNode == null) {
		return null;
	} else {
		return rootNode.getDelParNode(value);
	}
}

//找到节点A及以下树的最小节点,并删除它

public int delMin(Node node) {
	Node tempNode = node;
	while(tempNode.getLeftNode() != null) {
		tempNode = node.getLeftNode();	
	}
	del(tempNode.getData());
	return tempNode.getData();
}


//删除节点
public void del(int value) {
	if(rootNode == null) {
		System.out.println("没有root节点!删除失败!");
		return;
	}else {
		//需要找到待删除的节点
		Node delNode = search(value);
		if(delNode == null) {
			return;
		}
		//如果我们发现当前这颗二叉排序树只有一个结点
		if(rootNode.getLeftNode() == null && rootNode.getRightNode() == null) {
			rootNode = null;
			System.out.println("只有一个结点!删除失败!");
			return;
		}
		//去找到targetNode的父结点
		Node parent = searchParent(value);
		
		//1、待删除的节点是叶子节点
		if(delNode.getLeftNode() == null && delNode.getRightNode() == null) {
			if(parent.getLeftNode() != null && parent.getLeftNode().getData() == value) {
				parent.setLeftNode(null);
			}else {
				parent.setRightNode(null);
			}
			System.out.println("value:"+value+"是叶子节点,已经删除!");
		}else if(delNode.getLeftNode() != null && delNode.getLeftNode() != null){
			//2、待删除的节点是叶子节点:她有两个子节点,找到右子树最小的节点填删除的节点		
			delNode.setData(delMin(delNode.getRightNode()));
			System.out.println("value:"+value+"有两个子节点,已经删除!");
		}else {
			//3、待删除的节点不是叶子节点:它有一个子节点
			//如果删除的节点只有左子节点
			//如果要删除的结点有左子结点 
			if(delNode.getLeftNode() != null) {
				if(parent != null) {
					if(parent.getLeftNode().getData() == value) {
						parent.setLeftNode(delNode.getLeftNode());
					}else {
						parent.setRightNode(delNode.getLeftNode());
					}
				}else {
					rootNode = delNode.getLeftNode();
				}
				
			}else{
				if(parent != null) {
					if(parent.getLeftNode().getData() == value) {
						parent.setLeftNode(delNode.getRightNode());
					}else {
						parent.setRightNode(delNode.getRightNode());
					}
				}else {
					rootNode = delNode.getRightNode();
				}
			}
			System.out.println("value:"+value+"有一个子节点,已经删除!");
		}
		
		
			
		
		
		
		
		
		
		
		
	}
	
	
}
  • 遍历节点: 中序遍历
//中序遍历
public void infixOrder() {
	if(this.getLeftNode() !=null) {
		this.getLeftNode().infixOrder();
	}
	System.out.println(this.getData());
	if(this.getRightNode() !=null) {
		this.getRightNode().infixOrder();
	}	
}

全部代码:

package binarysorttree;

public class BinarySortTreeDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int[] arr = {7, 3, 10, 12, 5, 1, 9, 2};
//		BinarySortTreeDemo binarySortTreeDemo = new BinarySortTreeDemo();
		BinarySortTree binarySortTree = new BinarySortTree(null);
		for (int i = 0; i < arr.length; i++) {
			binarySortTree.add(new Node(arr[i]));
		}
		//中序遍历
		binarySortTree.infixOrder(); 1, 3, 5, 7, 9, 10, 12
		
		
		Node parent = binarySortTree.searchParent(2);
		System.out.println(parent.toString());
//		System.out.println(parent.getLeftNode().getData());
//		parent.getLeftNode().getData()
//		//删除节点
//		binarySortTree.del(2);
		//删除节点
//		binarySortTree.del(1);
		//删除节点
		binarySortTree.del(3);
//		//中序遍历
		binarySortTree.infixOrder(); 1, 3, 5, 7, 9, 10, 12
		
	}

}
//二叉树类
class BinarySortTree{
	private Node rootNode;

	public Node getRootNode() {
		return rootNode;
	}

	public void setRootNode(Node rootNode) {
		this.rootNode = rootNode;
	}

	public BinarySortTree(Node rootNode) {
		super();
		this.rootNode = rootNode;
	}
	
	//添加节点
	public void add(Node node) {
		if(this.rootNode == null) {
			this.rootNode = node;
			return;
		}
		this.rootNode.add(node);
	}
	
	//中序遍历
	public void infixOrder() {
		if(this.rootNode == null) {
			return;
		}
		this.rootNode.infixOrder();
	}
	
	//查找要删除的结点
	public Node search(int value) {
		if(rootNode == null) {
			return null;
		} else {
			return rootNode.getDelNode(value);
		}
	}
	
	//查找父结点
	public Node searchParent(int value) {
		if(rootNode == null) {
			return null;
		} else {
			return rootNode.getDelParNode(value);
		}
	}
	
	//找到节点A及以下树的最小节点,并删除它
	
	public int delMin(Node node) {
		Node tempNode = node;
		while(tempNode.getLeftNode() != null) {
			tempNode = node.getLeftNode();	
		}
		del(tempNode.getData());
		return tempNode.getData();
	}
	
	
	//删除节点
	public void del(int value) {
		if(rootNode == null) {
			System.out.println("没有root节点!删除失败!");
			return;
		}else {
			//需要找到待删除的节点
			Node delNode = search(value);
			if(delNode == null) {
				return;
			}
			//如果我们发现当前这颗二叉排序树只有一个结点
			if(rootNode.getLeftNode() == null && rootNode.getRightNode() == null) {
				rootNode = null;
				System.out.println("只有一个结点!删除失败!");
				return;
			}
			//去找到targetNode的父结点
			Node parent = searchParent(value);
			
			//1、待删除的节点是叶子节点
			if(delNode.getLeftNode() == null && delNode.getRightNode() == null) {
				if(parent.getLeftNode() != null && parent.getLeftNode().getData() == value) {
					parent.setLeftNode(null);
				}else {
					parent.setRightNode(null);
				}
				System.out.println("value:"+value+"是叶子节点,已经删除!");
			}else if(delNode.getLeftNode() != null && delNode.getLeftNode() != null){
				//2、待删除的节点是叶子节点:她有两个子节点,找到右子树最小的节点填删除的节点		
				delNode.setData(delMin(delNode.getRightNode()));
				System.out.println("value:"+value+"有两个子节点,已经删除!");
			}else {
				//3、待删除的节点不是叶子节点:它有一个子节点
				//如果删除的节点只有左子节点
				//如果要删除的结点有左子结点 
				if(delNode.getLeftNode() != null) {
					if(parent != null) {
						if(parent.getLeftNode().getData() == value) {
							parent.setLeftNode(delNode.getLeftNode());
						}else {
							parent.setRightNode(delNode.getLeftNode());
						}
					}else {
						rootNode = delNode.getLeftNode();
					}
					
				}else{
					if(parent != null) {
						if(parent.getLeftNode().getData() == value) {
							parent.setLeftNode(delNode.getRightNode());
						}else {
							parent.setRightNode(delNode.getRightNode());
						}
					}else {
						rootNode = delNode.getRightNode();
					}
				}
				System.out.println("value:"+value+"有一个子节点,已经删除!");
			}
			
			
				
			
			
			
			
			
			
			
			
		}
		
		
	}
	
}




//二叉排序树节点类
class Node{
	
	private int data;
	private Node leftNode;
	private Node rightNode;
	
	
	
	public Node(Integer data) {
		super();
		this.data = data;
	}
	public Integer getData() {
		return data;
	}
	public void setData(Integer data) {
		this.data = data;
	}
	public Node getLeftNode() {
		return leftNode;
	}
	public void setLeftNode(Node leftNode) {
		this.leftNode = leftNode;
	}
	public Node getRightNode() {
		return rightNode;
	}
	public void setRightNode(Node rightNode) {
		this.rightNode = rightNode;
	}
	@Override
	public String toString() {
		return "Node [data=" + data + "]";
	}
	
	
	//添加节点
	public void add(Node node) {
		if(node == null) {
			return;
		}
		if(node.getData() > this.getData()) {
			if(this.getRightNode() == null) {
				this.setRightNode(node);
			}else {
				this.getRightNode().add(node);
			}		
		}else {
			if(this.getLeftNode() == null) {
				this.setLeftNode(node);
			}else {
				this.getLeftNode().add(node);
			}
		}	
	}
	
	//中序遍历
	public void infixOrder() {
		if(this.getLeftNode() !=null) {
			this.getLeftNode().infixOrder();
		}
		System.out.println(this.getData());
		if(this.getRightNode() !=null) {
			this.getRightNode().infixOrder();
		}	
	}
	
	
	
	//删除节点
	//需要知道该节点和他的父节点
	//写两个方法
	//1、找到待删除的节点
	public Node getDelNode(int value) {
		if(value == this.getData()) {
			return this;
		}else {
			if(value > this.getData() && this.getRightNode() != null) {//右侧
				return this.getRightNode().getDelNode(value);
			}else if(value < this.getData() && this.getLeftNode() != null) {
				return this.getLeftNode().getDelNode(value);
			}else {
				return null;
			}
		}
		
	}
	
	//2、找到待删除的节点的父节点
	public Node getDelParNode(int value) {
		if((this.leftNode != null && this.getLeftNode().getData() == value)||
				(this.rightNode != null && this.getRightNode().getData() == value)) {
			return this;
		}else if(this.getData() > value && this.leftNode != null ) {
			return this.leftNode.getDelParNode(value);
		}else if(this.getData() <= value &&  this.rightNode != null) {
			return this.rightNode.getDelParNode(value);
		}else {
			return null;
		}
	}
	
	
	
	
}



版权声明:本文为wangjiaee原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。