修改 BinarySearchTree 使其平衡(AVL):Java
我需要修改我创建的二叉搜索树以确保它是平衡的。我只需要根据我的指示修改添加和删除方法。这就是我目前所拥有的:
package proj;
public class BinarySearchTree<T extends Comparable<T>>{
public static void main(String[] args) {
BinarySearchTree<Integer> tree = new BinarySearchTree<Integer>();
tree.add(5);
tree.add(1);
tree.add(2);
tree.add(6);
}
private Node<T> root;
private int size;
String inorder = "";
String preorder = "";
public BinarySearchTree(){
root = null;
size = 0;
}
//adds a new item to the queue
public void add(T obj) {
Node<T> n = new Node<T>(obj);
if( root == null ) {
root = n;
} else {
add( root, n );
}
size++;
}
private void add(Node<T> subtree, Node<T> n) {
if( subtree.getValue().compareTo(n.getValue()) > 0 ) {
if( subtree.getLeftChild() == null ) {
subtree.setLeftChild(n);
n.setParent(subtree);
} else {
add( subtree.getLeftChild(), n );
}
} else {
if( subtree.getRightChild() == null ) {
subtree.setRightChild(n);
n.setParent(subtree);
} else {
add( subtree.getRightChild(), n );
}
}
}
//returns the head of the queue
public T peek(){
Node<T> current = root;
while(current.getLeftChild() != null){
current = current.getLeftChild();
}
return current.getValue();
}
//removes the head of the queue and returns it
public T remove(){
if(root == null){
return null;
}
Node<T> current = root;
while(current.getLeftChild() != null){
current = current.getLeftChild();
}
if( current.getParent() == null ) {
root = current.getRightChild();
if(root != null){
root.setParent(null);
}
} else {
current.getParent().setLeftChild(current.getRightChild());
if(current.getRightChild() != null){
current.getRightChild().setParent(current.getParent());
}
}
size--;
return current.getValue();
}
//returns the position of an element in the queue, or -1 if it is not found
public int search(T searchItem){
String tempOrdered = inorder(root);
for(int i = 0; i<tempOrdered.length(); i++){
if(String.valueOf(tempOrdered.charAt(i)).equals(searchItem.toString())){
return i;
}
}
return -1;
}
//returns number of nodes in the tree
//returns the total number of elements in the queue
public int getSize(){
return size;
}
public String inorder() {
inorder = "";
if( root == null )
return inorder;
return inorder(root);
}
//returns an in-order, comma-separated string of every element in the queue
private String inorder(Node<T> n){
if(n.getLeftChild() != null){
inorder(n.getLeftChild());
}
inorder += n.getValue();
if(n.getRightChild() != null){
inorder(n.getRightChild());
}
return inorder;
}
public String preorder() {
preorder = "";
if( root == null )
return preorder;
return preorder(root);
}
//returns a pre-ordered, comma-separated string of every element in the queue
private String preorder(Node<T> n){
preorder+= n.getValue();
if(n.getLeftChild() != null){
preorder(n.getLeftChild());
}
if(n.getRightChild() != null){
preorder(n.getRightChild());
}
return preorder;
}
//returns the height of the tree; returns -1 if the tree is empty
public int height(Node<T> n){
if(n == null){
return -1;
}
return Math.max(height(n.getLeftChild()), height(n.getRightChild()))+ 1;
}
//returns the root node
public Node<T> getRoot(){
return root;
}
}
我不是在寻找有人引导我完成这项任务 - 只是寻找一些关于我应该如何去做这件事的建议,这样我就不会中途破坏代码。我是猜测我需要做一些事情来检查每次添加或删除某些内容时树的平衡系数,然后在树不平衡时重建树或“旋转”。
感谢您提前提供的任何建议。 :) 感谢所有的提示。
-克里斯
I need to modify a Binary Search Tree that I created to assure that it is balanced. I only need to modify the add and remove methods, according to my instructions. Here's what I currently have:
package proj;
public class BinarySearchTree<T extends Comparable<T>>{
public static void main(String[] args) {
BinarySearchTree<Integer> tree = new BinarySearchTree<Integer>();
tree.add(5);
tree.add(1);
tree.add(2);
tree.add(6);
}
private Node<T> root;
private int size;
String inorder = "";
String preorder = "";
public BinarySearchTree(){
root = null;
size = 0;
}
//adds a new item to the queue
public void add(T obj) {
Node<T> n = new Node<T>(obj);
if( root == null ) {
root = n;
} else {
add( root, n );
}
size++;
}
private void add(Node<T> subtree, Node<T> n) {
if( subtree.getValue().compareTo(n.getValue()) > 0 ) {
if( subtree.getLeftChild() == null ) {
subtree.setLeftChild(n);
n.setParent(subtree);
} else {
add( subtree.getLeftChild(), n );
}
} else {
if( subtree.getRightChild() == null ) {
subtree.setRightChild(n);
n.setParent(subtree);
} else {
add( subtree.getRightChild(), n );
}
}
}
//returns the head of the queue
public T peek(){
Node<T> current = root;
while(current.getLeftChild() != null){
current = current.getLeftChild();
}
return current.getValue();
}
//removes the head of the queue and returns it
public T remove(){
if(root == null){
return null;
}
Node<T> current = root;
while(current.getLeftChild() != null){
current = current.getLeftChild();
}
if( current.getParent() == null ) {
root = current.getRightChild();
if(root != null){
root.setParent(null);
}
} else {
current.getParent().setLeftChild(current.getRightChild());
if(current.getRightChild() != null){
current.getRightChild().setParent(current.getParent());
}
}
size--;
return current.getValue();
}
//returns the position of an element in the queue, or -1 if it is not found
public int search(T searchItem){
String tempOrdered = inorder(root);
for(int i = 0; i<tempOrdered.length(); i++){
if(String.valueOf(tempOrdered.charAt(i)).equals(searchItem.toString())){
return i;
}
}
return -1;
}
//returns number of nodes in the tree
//returns the total number of elements in the queue
public int getSize(){
return size;
}
public String inorder() {
inorder = "";
if( root == null )
return inorder;
return inorder(root);
}
//returns an in-order, comma-separated string of every element in the queue
private String inorder(Node<T> n){
if(n.getLeftChild() != null){
inorder(n.getLeftChild());
}
inorder += n.getValue();
if(n.getRightChild() != null){
inorder(n.getRightChild());
}
return inorder;
}
public String preorder() {
preorder = "";
if( root == null )
return preorder;
return preorder(root);
}
//returns a pre-ordered, comma-separated string of every element in the queue
private String preorder(Node<T> n){
preorder+= n.getValue();
if(n.getLeftChild() != null){
preorder(n.getLeftChild());
}
if(n.getRightChild() != null){
preorder(n.getRightChild());
}
return preorder;
}
//returns the height of the tree; returns -1 if the tree is empty
public int height(Node<T> n){
if(n == null){
return -1;
}
return Math.max(height(n.getLeftChild()), height(n.getRightChild()))+ 1;
}
//returns the root node
public Node<T> getRoot(){
return root;
}
}
I'm not looking for someone to walk me through this assignment - simply looking for some advice as to how I should go about doing this so that I don't break the code half way in. I'm guessing that I'll need to do something to the effect of checking the balance factor of the tree each time something is added or removed, then reconstruct the tree or 'rotate' when it's unbalanced.
Thanks for any given advice in advance. :) Appreciate all the tips.
-Chris
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
维基百科上的 AVL 树 文章提供了实现这种自平衡树所需的一切(我特别喜欢图片显示重新平衡所需的旋转)。基本上,您需要实现左右树旋转,并根据本文中给出的规则在
add
和remove
方法中使用它。如果您更具冒险精神,请尝试实现红黑树。可以在算法简介中找到带有伪代码的详细描述。
The AVL tree article on Wikipedia gives all you need to implement this kind of self-balanced tree (I especially like the picture showing rotations needed for rebalancing). Basically you need to implement left and right tree rotation and use it in your
add
andremove
methods according to the rules given in the article.If you are more adventurous, try implementing a red-black tree. A good description with pseudo code can be found in Introduction to Algorithms.