我正在尝试生成1000个唯一正integer
个数字并将其插入到大小为1000的AVL树中。这些正数没有上限。但为了方便起见,我给出了上限Integer.MAX_VALUE。我的问题是,我可以向arraylist添加1000个数字但是当我尝试将数字从arraylist添加到avl树时,它只添加了一些这些数字(即39个1000个数字),我花了一天时间来解决它。任何帮助表示赞赏。
这是我的AVL Tree课程:
import java.util.Stack;
public class AVLTree {
public int findHeight(AVLNode node){
if(node != null)
return node.height;
return 0;
}
public int getBalance(AVLNode node){
if(node != null)
return findHeight(node.left) - findHeight(node.right);
return 0;
}
public AVLNode insertNumber(AVLNode node, int data){
if(node == null) {
return (new AVLNode(data));
}
//If current node's number is greater than newly added node's number, add it to the right
if(node.number < data){
node.right = insertNumber(node.right,data);
}
//If current node's number is less greater than newly added node's number, add it to the left
else{
node.left = insertNumber(node.left,data);
}
//update node's height
node.height = Math.max(findHeight(node.left), findHeight(node.right)) + 1;
int balDiff = getBalance(node);
// Left Rotate
if (balDiff > 1 && data < node.left.number) {
return rotateRight(node);
}
// Right Rotate
if (balDiff < -1 && data > node.right.number) {
return rotateLeft(node);
}
// Left Right Rotate
if (balDiff > 1 && data > node.left.number) {
node = rotateLeft(node.left);
return rotateRight(node);
}
// Right Left Rotate
if (balDiff < -1 && data < node.right.number) {
node = rotateRight(node.right);
return rotateLeft(node);
}
return node;
}
public AVLNode rotateRight(AVLNode y) {
AVLNode x = y.left;
AVLNode T2 = x.right;
// Rotation
x.right = y;
y.left = T2;
// update their heights
x.height = Math.max(findHeight(x.left), findHeight(x.right)) + 1;
y.height = Math.max(findHeight(y.left), findHeight(y.right)) + 1;
return x;
}
public AVLNode rotateLeft(AVLNode x) {
AVLNode y = x.right;
AVLNode T2 = y.left;
// Rotation
y.left = x;
x.right = T2;
// update their heights
x.height = Math.max(findHeight(x.left), findHeight(x.right)) + 1;
y.height = Math.max(findHeight(y.left), findHeight(y.right)) + 1;
return y;
}
public void printInorder(AVLNode root){
if(root != null){
printInorder(root.left);
System.out.println(root.number);
printInorder(root.right);
}
}
public int findMaximum(AVLNode node){
//Recursive solution
/*if(node.right == null) {
return node.number;
} else {
return findMaximum(node.right);
}*/
//Iterative solution
while(node.right != null){
node = node.right;
}
return node.number;
}
public int findMinimum(AVLNode node){
//Recursive solution
/*
if(node.left == null)
return node.number;
else
return findMinimum(node.left);
*/
//Iterative solution
while(node.left != null){
node = node.left;
}
return node.number;
}
public double getSum(AVLNode node){
if(node == null)
return 0;
return node.number + getSum(node.left) + getSum(node.right);
}
public int getSumSmaller(AVLNode root, int data){
int sum = 0;
Stack<AVLNode> s1 = new Stack<AVLNode>();
Stack<AVLNode> s2 = new Stack<AVLNode>();
s1.push(root);
while(!s1.isEmpty()){
AVLNode tmp = s1.pop();
s2.push(tmp);
if(tmp.left != null && tmp.left.number < data){
s1.push(tmp.left);
sum = sum + tmp.left.number;
}
if(tmp.right != null && tmp.right.number < data){
s1.push(tmp.right);
sum = sum + tmp.right.number;
}
}
return sum;
}
}
这是我的主Java类:
public static void main(String[] args) {
Random rnd = new Random();
ArrayList<Integer> ar = new ArrayList<>();
int counter = 0;
AVLNode root = null;
AVLTree avltree1 = new AVLTree();
//AVLTree avltree2 = new AVLTree();
//AVLTree avltree3 = new AVLTree();
while(counter < 1000) {
int val;
do{
val = rnd.nextInt(Integer.MAX_VALUE);
}while(ar.contains(val));
ar.add(val);
}
long initTime = System.nanoTime();
for(int i = 0;i < counter;i++){
root = avltree1.insertNumber(root,ar.get(i));
}
long finishTime = System.nanoTime();
avltree1.printInorder(root);
long durationTime = finishTime-initTime;
}
答案 0 :(得分:0)
我可以立即看到的一个问题是循环
while(counter < 1000) {
int val;
do{
val = rnd.nextInt(Integer.MAX_VALUE);
}while(ar.contains(val));
ar.add(val);
}
永远不会终止,因为变量counter
不会递增。
您的AVLTree.insert()
方法存在较大问题。请使用以下代码:
// Right Left Rotate
if (balDiff < -1 && data < node.right.number) {
node = rotateRight(node.right); // node = node.right.left;
return rotateLeft(node); // return node.right
}
如果root
是原始节点,则此段代码将返回root.right.left.right
。所以在循环中
for(int i = 0;i < counter;i++){
root = avltree1.insertNumber(root,ar.get(i));
}
root
的值偶尔会更深入到树中。难怪当你打电话给printInorder(root);
时,它只打印部分树。
这不是你唯一的问题。为了更多地了解正在发生的事情,我建议创建一个更有用的方法来显示树:
public void printOut(AVLNode root)
{
System.out.print("(");
if (root != null) {
System.out.print(root.number);
printOut(root.left);
printOut(root.right);
}
System.out.print(")");
}
然后将原始循环修改为
for(int i = 0;i < counter;i++){
root = avltree1.insertNumber(root,ar.get(i));
avltree1.printOut(root);
}
将树的大小从1000缩小,以了解正在进行的操作。您可能希望跟踪原始根并在循环中调用printOut(originalRoot);
。