温习之数据结构--二叉树

    直接代码

    节点类

package tree;

public class Node {
	private long id;//数据项
	private String data;
	private Node leftChild;//左子节点
	private Node rightChild;//右子节点
	private Node PrarentNode; //父节点
	private boolean isLeft;	//是否为左子节点
	
	public Node(long id,String data){
		this.id = id;
		this.data = data;
	}

	public long getId() {
		return id;
	}

	public void setData(long id) {
		this.id = id;
	}

	public Node getLeftChild() {
		return leftChild;
	}

	public void setLeftChild(Node leftChild) {
		this.leftChild = leftChild;
	}

	public Node getRightChild() {
		return rightChild;
	}

	public void setRightChild(Node rightChild) {
		this.rightChild = rightChild;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}

	public Node getPrarentNode() {
		return PrarentNode;
	}

	public void setPrarentNode(Node prarentNode) {
		PrarentNode = prarentNode;
	}

	public boolean isLeft() {
		return isLeft;
	}

	public void setLeft(boolean isLeft) {
		this.isLeft = isLeft;
	}
}



    二叉树类

package tree;

public class Tree {
	//根节点
	private Node root;
	
	/**
	 * 插入
	 * @param value
	 */
	public void insert(long id,String data){
		Node newNode = new Node(id,data);
		Node current = root;
		Node parent;
		//第一次插入
		if(root == null){
			root = newNode;
			return;
		}else{
			while(true){
				parent = current;
				//如果当前节点数据比插入的大,则向左
				if(current.getId() > id){
					current = current.getLeftChild();
					if(current == null){
						parent.setLeftChild(newNode);
						//设置该节点的父节点
						newNode.setPrarentNode(parent);
						//设置该节点是左子节点
						newNode.setLeft(true);
						return;
					}
				}else{
					current = current.getRightChild();
					
					if(current == null){
						parent.setRightChild(newNode);
						//设置该节点的父节点
						newNode.setPrarentNode(parent);
						//设置该节点是右子节点
						newNode.setLeft(false);
						return;
					}
				}
			}
		}
	}
	/**
	 * 查找
	 */
	public Node find(long id){
		Node current = root;
		while(current.getId() != id){
			if(current.getId() > id){
				current = current.getLeftChild();
			}else{
				current = current.getRightChild();
			}
			//如果找不到,则返回空
			if(current == null){
				return null;
			}
		}
		return current;
	}
	
	/**
	 * 删除
	 * @param value
	 */
	public boolean delete(long value){
		//找到此节点
		Node node = find(value);
		if(node == null){
			return false;
		}
		//如果是叶子节点,将父节点对应子节点的引用改变为空
		if(node.getLeftChild() == null && node.getRightChild() == null){
			//如果是根节点,则整个树为就一个节点,直接root = null;
			if(node == root){
				root = null;
			}else{
				if(node.isLeft()){
					node.getPrarentNode().setLeftChild(null);
				}else {
					node.getPrarentNode().setRightChild(null);
				}
			}
		}else if(node.getRightChild() == null){
			if(node == root){
				root = node.getLeftChild();
			}else if(node.isLeft()){
				node.getPrarentNode().setLeftChild(node.getLeftChild());
			}else{
				node.getPrarentNode().setRightChild(node.getLeftChild());
			}
		}else if(node.getLeftChild() == null){
			if(node == root){
				root = node.getRightChild();
			}else if(node.isLeft()){
				node.getPrarentNode().setLeftChild(node.getRightChild());
			}else{
				node.getPrarentNode().setRightChild(node.getRightChild());
			}
		}
		//该节点有左右子节点
		else {
			//找到中序后继节点
			Node successor = findSuccessor(node);
			if(node == root){
				//如果中序后继节点和该节点的右子节点相同,则中序后继节点必为左子节点,否则必为右子节点
				if(successor != node.getRightChild()){
					//该节点的右子节点作为中序后继的右子节点
					successor.setRightChild(node.getRightChild());
					//中序后继节点作为该节点右子节点的父节点
					node.getRightChild().setPrarentNode(successor);
					//将原来中序后继节点的父节点的父节点的左子节点设置为null
					successor.getPrarentNode().setLeftChild(null); 
				}
				successor.setPrarentNode(null);
				//把该节点的左子节点作为中序后继节点的左子节点
				successor.setLeftChild(node.getLeftChild());
				//把中序后继节点作为该节点左节点的父节点
				node.getLeftChild().setPrarentNode(successor);
				//将中序后继节点作为root
				root = successor;
			}else {
				successor.setLeftChild(node.getLeftChild());
				node.getLeftChild().setPrarentNode(successor);
				if(node.getRightChild() != successor){
					successor.setRightChild(node.getRightChild());
					node.getRightChild().setPrarentNode(successor);
					//将中序后继节点的父节点的左子树设置为null
					successor.getPrarentNode().setLeftChild(null);
				}else{
					successor.getPrarentNode().setRightChild(successor.getRightChild());
				}
				successor.setPrarentNode(node.getPrarentNode());
				successor.setLeft(node.isLeft());
				if(successor.isLeft()){
					node.getPrarentNode().setLeftChild(successor);
				}else{
					node.getPrarentNode().setRightChild(successor);
				}
			}
		}
		return true;
	}
	
	/**
	 * 根据要删除的节点找到中序后继节点,
	 * 其实就是该比该节点大,但是最接近该节点的节点
	 * @param node
	 * @return
	 */
	public Node findSuccessor(Node node){
		Node current = node.getRightChild();
		while(true){
			Node left = current.getLeftChild();
			if(left == null){
				return current;
			}
			current = left;
		}
	}
	
	
	/**
	 * 前序遍历
	 * 
	 * 访问根节点
	 * 前序遍历左子树
	 * 前序遍历右子树
	 * 
	 */
	public void frontOrder(Node localNode){
		if(localNode != null){
			System.out.println(localNode.getId()+","+localNode.getData());
			//遍历左子树
			frontOrder(localNode.getLeftChild());
			//遍历右子树
			frontOrder(localNode.getRightChild());
		}
	}
	
	/**
	 * 中序遍历
	 * 
	 * 中序遍历左子树
	 * 访问根节点
	 * 中序遍历右子树
	 * @return
	 */
	public void middleOrder(Node localNode){
		if(localNode != null){
			middleOrder(localNode.getLeftChild());
			System.out.println(localNode.getId()+","+localNode.getData());
			middleOrder(localNode.getRightChild());
		}
	}
	public Node getRoot() {
		return root;
	}
	
	/**
	 * 后序遍历
	 * 
	 * 后序遍历左子树
	 * 后续遍历右子树
	 * 访问根节点
	 */
	public void afterOrder(Node localNode){
		if(localNode != null){
			afterOrder(localNode.getLeftChild());
			afterOrder(localNode.getRightChild());
			System.out.println(localNode.getId()+","+localNode.getData());
		}
	}
	
}



    测试类

    

package tree;

public class TestTree {
	public static void main(String[] args) {
		Tree t = new Tree();
		t.insert(10,"A");
		t.insert(20,"B");
		t.insert(15,"C");
		t.insert(3,"D");
		t.insert(4,"E");
		t.insert(90,"F");
//		t.insert(26,"G");
//		t.insert(23,"H");
//		t.insert(29,"I");
		t.insert(100,"J");
		t.delete(20);
//		System.out.println(t.getRoot().getData());
//		System.out.println(t.getRoot().getRightChild().getData());
//		System.out.println(t.getRoot().getRightChild().getLeftChild().getData());
//		System.out.println(t.getRoot().getLeftChild().getData());
		t.frontOrder(t.getRoot());
	}
}





转载于:https://my.oschina.net/U74F1zkKW/blog/368127

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值