数据结构_树结构

       树结构同时集成了数组查找迅速和链表添删迅速的优点。先来看看普通的搜索二叉树的实现:

package com.wly.algorithmbase.datastructure;

/**
 * 二叉搜索树
 * @author wly
 */
public class BinaryTree {

	private static BTreeNode root;
	public static void main(String[] args) {
		
		BinaryTree tree = new BinaryTree();
		tree.insert(new BTreeNode(11, 23));
		tree.insert(new BTreeNode(6, 12));
		tree.insert(new BTreeNode(16, 51));
		tree.insert(new BTreeNode(3, 32));
		tree.insert(new BTreeNode(9, 42));
		tree.insert(new BTreeNode(14, 52));
		tree.insert(new BTreeNode(19, 62));
		tree.insert(new BTreeNode(13, 72));
		tree.insert(new BTreeNode(12, 82));
				
		tree.find(2);
		tree.print(root);
		tree.delete(11);
		tree.print(root);
	}

	/**
	 * 插入节点
	 * 关键在于缓存当前节点,检查当前节点的子节点
	 */
	public void insert(BTreeNode node) {
		if(root == null) {
			root = node;
		} else {
			BTreeNode currentNode = root;
			BTreeNode parent;
			while(true) {
				parent = currentNode;
				if(node.getKey() < currentNode.getKey()) {
					currentNode = currentNode.getLeft();
					if(currentNode == null) {
						parent.setLeft(node);
						return;
					}
				} else {
					currentNode = currentNode.getRight();
					if(currentNode == null) {
						parent.setRight(node);
						return;
					}
				}
			}
		}
	}

	/**
	 * 根据关键字查找
	 */
	public BTreeNode find(int key) {
		BTreeNode current = root;
		while(true) {
			if(current == null) {
				System.out.println("未查找到key=" + key + "的节点");
				return null;
			} else {
				if(current.getKey() > key) {
					current = current.getLeft();
				} else if(current.getKey() < key) {
					current = current.getRight();
				} else {
					System.out.println("查找到key=" + key + ",data=" + current.getData() + "的节点");
					return current;
				}
			}
		}
	}
	
	/**
	 * 根据key值删除节点,删除的成功与否取决于是否存在该节点
	 * @param key
	 * @return true删除成功,false删除失败
	 */
	public boolean delete(int key) {
		BTreeNode deleteNode = find(key);
		if(deleteNode == null) {
			System.out.println("未查找到key=" + key + "的节点,无法进行删除");
			return false;
		} else {
			removeFromTree(deleteNode);
			System.out.println("成功删除key=" + key + "的节点");
			return true;
		}
	}
	
	/**
	 * 将自身从树中移除
	 */
	public void removeFromTree(BTreeNode node) {
		//1.自身不包含子节点
		if(node.getLeft() == null && node.getRight() == null) { 
			if(node.isLeft) {
				node.getParent().setLeft(null);
			} else {
				node.getParent().setRight(null);
			}
		}
		
		//2.包含一个子节点
		if(node.getLeft() != null && node.getRight() == null) {
			if(node.isLeft) {
				node.getParent().setLeft(node.getLeft());
			} else {
				node.getParent().setRight(node.getLeft());
			}
		} else if(node.getLeft() == null && node.getRight() != null) {
			if(node.isLeft) {
				node.getParent().setLeft(node.getRight());
			} else {
				node.getParent().setRight(node.getRight());
			}
		}
				
		//3.包含两个子节点
		//查找后继节点
		BTreeNode successorNode = node.getSuccessor(node);		
		//从树种移除该后继节点
		if(successorNode.getParent() != null) {
			if(successorNode.isLeft) {
				successorNode.getParent().setLeft(null);
			} else {
				successorNode.getParent().setRight(null);
			}
		}
		successorNode.setLeft(node.getLeft());
		successorNode.setRight(node.getRight());
		//从树中移除待删除节点,并用后继节点替换
		if(node.getParent() != null) {
			if(node.isLeft) {
				node.getParent().setLeft(successorNode);
			} else {
				node.getParent().setRight(successorNode);
			}
		} else {
			root = successorNode;
		}
	}
	
	/**
	 * 打印树结构
	 */
	public void print(BTreeNode node) {
		if(node != null) {
			System.out.print(node.getKey() + "|" + node.getData());
			System.out.println();
		}
		if(node.getLeft() != null) {
			print(node.getLeft());
		}
		if(node.getRight() != null) {
			print(node.getRight());
		}
	}
	
}

/**
 * 节点类
 * @author wly
 *
 */
class BTreeNode {
	private BTreeNode left;
	private BTreeNode right;
	
	private BTreeNode parent;
	
	boolean isLeft; //是左子节点吗,否则就是右子节点
	
	int key; //检索关键字
	int data; //包含的数据对象
	
	public BTreeNode() {
		super();
	}
	
	public BTreeNode(int key, int data) {
		super();
		this.key = key;
		this.data = data;
	}
	
	public BTreeNode getLeft() {
		return left;
	}
	public void setLeft(BTreeNode left) {
		this.left = left;
		if(left != null) {
			left.parent = this;
			left.isLeft = true;
		}
	}
	public BTreeNode getRight() {
		return right;
	}
	public void setRight(BTreeNode right) {
		this.right = right;
		if(right != null) {
			right.parent = this;
			right.isLeft = false;
		}
	}
	
	public BTreeNode getParent() {
		return parent;
	}

	public void setParent(BTreeNode parent) {
		this.parent = parent;
		
	}
	public int getKey() {
		return key;
	}
	public void setKey(int key) {
		this.key = key;
	}
	public int getData() {
		return data;
	}
	public void setData(int data) {
		this.data = data;
	}
	
	/**
	 * 返回指定节点的后继节点(即大于指定节点的最小节点)
	 * @param node
	 * @return
	 */
	public BTreeNode getSuccessor(BTreeNode node) {
		BTreeNode result = node.getRight(); //先取得右节点
		if(result == null) {
			return null;
		} else {
			while(result.getLeft() != null) {
				result = result.getLeft();
			}
		}
		return result;
	}
}

运行结果:

未查找到key=2的节点
11|23
6|12
3|32
9|42
16|51
14|52
13|72
12|82
19|62
查找到key=11,data=23的节点
成功删除key=11的节点
12|82
6|12
3|32
9|42
16|51
14|52
13|72
19|62

O啦~~~

转载请保留出处:http://blog.csdn.net/u011638883/article/details/17120363

谢谢!!


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值