数据结构_树结构

原创 2013年12月05日 13:08:47

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

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

谢谢!!


相关文章推荐

C# 一个自己写的树结构代码(2)-Array,HashTable,List,String数据结构操作封装

Array,HashTable,List,String数据结构操作封装。仅仅实现了功能,没有考虑性能。如果有更好的实现方式,希望能互相交流。 public class ArrayUt...
  • kzerg
  • kzerg
  • 2016年10月20日 11:32
  • 398

<C/C++数据结构>常见的树结构

1.所有非叶子结点至多拥有两个儿子(Left和Right); 2.所有结点存储一个关键字; 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;...

数据结构——树结构基础

在之前的博文中,我们讲过:所谓数据结构,其实就是研究组织大量数据的方法,或者说研究如何存储数据。 那么接下来我们思考一个问题:如何存储一个学校的学生信息? 我们当然可以定义一个结构体,其中存储着学...

树结构应用之MySQL索引背后的数据结构及算法原理

MySQL索引背后的数据结构及算法原理
  • zolalad
  • zolalad
  • 2014年07月28日 09:30
  • 740

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

本篇博文主要介绍几个特殊的二叉树,堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、线索二叉树,它们在解决实际问题中有着非常重要的应用。...

使用js进行二叉树结构数据与数组结构数据的互相转化

简单的说下树形数据的结构:"type": "logic", "content": "and", "left": { "type": "leaf", "content": "=", ...

java树结构,树结构表设计

  • 2009年12月01日 12:08
  • 3KB
  • 下载

数据库为什么要用B+树结构--MySQL索引结构的实现

B+树在数据库中的应用 { 为什么使用B+树?言简意赅,就是因为: 1.文件很大,不可能全部存储在内存中,故要存储到磁盘上 2.索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数(为什么使用B-/...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构_树结构
举报原因:
原因补充:

(最多只允许输入30个字)