JAVA实现,以及JFrame 结果展示
package com.example.fndemo.tree;
import java.util.Stack;
public class AVLTree {
Node<Integer> rootNode;
public static void main(String[] args) {
Integer[] datas = {2, 1, 0, 3, 4, 5, 6, 9, 8, 7};
AVLTree avlTree = new AVLTree();
for (Integer data : datas) {
avlTree.insert(data);
}
avlTree.midTraversing();
System.out.println();
DrawTree drawTree = new DrawTree(avlTree.rootNode);
}
public void insert(Integer data) {
if (null == rootNode) {
rootNode = new Node<Integer>(data);
return;
}
Node insert = new Node<Integer>(data).insert(rootNode);
this.adjust(insert);
System.out.println("是否插入成功:" + (null != insert.getParent()) + " 当前key:" + insert.getKey() + " 父亲key:" + (null == insert.getParent() ? null : insert.getParent().getKey()));
}
public Node<Integer> getRootNode() {
return rootNode;
}
public void adjust(Node leafNode){
Node current = leafNode;
int index=1;
while (current!=null&&index<5){
if (current.getBalance() > 1) {
if (current.getLeftChild().getBalance() < 0) {
rotateLeft(current.getLeftChild());
}
rotateRight(current);
return;
}
if (current.getBalance() < -1) {
if (current.getRightChild().getBalance() > 0) {
rotateRight(current.getRightChild());
}
rotateLeft(current);
return;
}
current=current.getParent();
index++;
}
}
public void rotateLeft(Node currentNode){
Node parent = currentNode.getParent();
Node rightChild = currentNode.getRightChild();
Node rightChildLeftChild = rightChild.getLeftChild();
currentNode.setParent(rightChild);
currentNode.setRightChild(rightChildLeftChild);
rightChild.setParent(parent);
rightChild.setLeftChild(currentNode);
if (parent != null) {
if (parent.getRightChild().equals(currentNode)) {
parent.setRightChild(rightChild);
}
if (parent.getLeftChild().equals(currentNode)) {
parent.setRightChild(rightChild);
}
}else{
rootNode=rightChild;
}
if (null != rightChildLeftChild) {
rightChildLeftChild.setParent(currentNode);
}
}
public void rotateRight(Node currentNode){
Node parent = currentNode.getParent();
Node leftChild = currentNode.getLeftChild();
Node leftChildRightChild = leftChild.getRightChild();
leftChild.setRightChild(currentNode);
leftChild.setParent(parent);
currentNode.setParent(leftChild);
currentNode.setLeftChild(leftChildRightChild);
if (parent != null) {
if (parent.getRightChild()!=null&&parent.getRightChild().equals(currentNode)) {
parent.setRightChild(leftChild);
}
if (parent.getLeftChild()!=null&&parent.getLeftChild().equals(currentNode)) {
parent.setRightChild(leftChild);
}
}else {
rootNode=leftChild;
}
if (null != leftChildRightChild) {
leftChildRightChild.setParent(currentNode);
}
}
public void preTraversing() {
Node currentNode = rootNode;
Node preNode = currentNode;
Stack<Node> nodeStack = new Stack<>();
nodeStack.push(rootNode);
while (!nodeStack.isEmpty()) {
currentNode = nodeStack.peek();
if (currentNode != null) {
System.out.print(currentNode.getData() + " ");
nodeStack.pop();
}
if (currentNode != null && currentNode.getRightChild() != null) {
nodeStack.push(currentNode.getRightChild());
}
if (currentNode != null && currentNode.getLeftChild() != null) {
nodeStack.push(currentNode.getLeftChild());
}
}
}
public void midTraversing() {
Node currentNode = rootNode;
Node preNode = rootNode;
Stack<Node> nodeStack = new Stack<>();
nodeStack.push(rootNode);
while (!nodeStack.isEmpty()) {
while (currentNode != null && currentNode.getLeftChild() != null) {
currentNode = currentNode.getLeftChild();
nodeStack.push(currentNode);
}
currentNode = nodeStack.pop();
System.out.print(currentNode.getData() + " ");
currentNode = currentNode.getRightChild();
if (currentNode != null) {
nodeStack.push(currentNode);
}
}
}
public void postTraversing() {
Node currentNode = rootNode;
Node preNode = rootNode;
Stack<Node> nodeStack = new Stack<>();
nodeStack.push(rootNode);
while (!nodeStack.isEmpty()) {
currentNode = nodeStack.peek();
if ((currentNode.getLeftChild() == null && currentNode.getRightChild() == null) || currentNode.getRightChild() == preNode || currentNode.getLeftChild() == preNode) {
System.out.print(currentNode.getData() + " ");
preNode = currentNode;
nodeStack.pop();
continue;
}
if (currentNode.getRightChild() != null) {
nodeStack.push(currentNode.getRightChild());
}
if (currentNode.getLeftChild() != null) {
nodeStack.push(currentNode.getLeftChild());
}
}
}
}
package com.example.fndemo.tree;
import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Stack;
public class DrawTree extends JFrame {
PositionMap positionMap;
public DrawTree(Node root) throws HeadlessException {
this.setSize(800, 600);
this.setTitle("窗口测试");
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setContentPane(new EVLDrawPanel(root));
double rate = Math.tan(Math.toRadians(35));
this.positionMap = new PositionMap(root,100,500,30,rate);
}
public class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class EVLDrawPanel extends JPanel {
Node root;
public EVLDrawPanel(Node root) {
this.root = root;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawTree(g);
}
public void drawTree(Graphics g) {
Node currentNode = root;
Stack<Node> nodeStack = new Stack<>();
nodeStack.push(root);
while (!nodeStack.isEmpty()) {
currentNode = nodeStack.peek();
if (currentNode != null) {
drawCycle(currentNode, g);
nodeStack.pop();
}
if (currentNode != null && currentNode.getRightChild() != null) {
nodeStack.push(currentNode.getRightChild());
}
if (currentNode != null && currentNode.getLeftChild() != null) {
nodeStack.push(currentNode.getLeftChild());
}
}
}
public void drawCycle(int x, int y, int radius, Graphics g) {
g.drawOval(x - radius, y - radius, radius * 2, radius * 2);
}
public void drawCycle(Node node, Graphics g) {
int radius = 5;
Point point = positionMap.get(node, root);
drawCycle(point.x, point.y, radius, g);
g.drawString(String.valueOf(node.getData()), point.x + radius + 3, point.y + radius / 2);
if (node.getParent() != null) {
Point father = positionMap.get(node.getParent(), root);
g.drawLine(point.x, point.y, father.x, father.y);
}
}
}
class PositionMap {
HashMap<Integer, HashMap<Integer, Point>> map = new HashMap<>();
public int maxLevel = 0;
PositionMap(Node rootNode,int startX, int startY, int radiusMargin,double rate) {
this.maxLevel = rootNode.getHeight();
generator(startX, startY, radiusMargin,rate);
}
void generator(int startX, int startY, int radiusMargin,double rate) {
for (int level = this.maxLevel; level > 0; level--) {
HashMap<Integer, Point> item = new HashMap<>();
map.put(level, item);
int nodeNumber = (int) Math.pow(2, level - 1);
for (int i = 0; i < nodeNumber; i++) {
item.put(i, new Point(startX + radiusMargin * i, startY));
}
startX = startX + radiusMargin / 2;
radiusMargin = radiusMargin * 2;
int h = (int) Math.round(rate * radiusMargin / 2);
startY = startY - h;
}
}
public Point get(Integer level, Integer index) {
assert level > -1 && level <= maxLevel;
return map.get(level).get(index);
}
public Point get(Node node, Node rootNode) {
assert null != node;
return pointCalc(node, rootNode);
}
public Point pointCalc(Node node, Node rootNode) {
int index = 0;
int level = 1;
Node currentNode = rootNode;
while (currentNode != null) {
if (currentNode.equals(node)) {
break;
}
if (currentNode.getKey().intValue() > node.getKey().intValue()) {
currentNode = currentNode.getLeftChild();
index = (index + 1) * 2 - 2;
level++;
}
if (currentNode.getKey().intValue() < node.getKey().intValue()) {
currentNode = currentNode.getRightChild();
index = (index + 1) * 2 - 1;
level++;
}
}
if (currentNode == null) {
System.out.println("节点未找到");
return null;
}
return get(level, index);
}
}
}
package com.example.fndemo.tree;
import java.util.Objects;
class Node<T> {
private T data;
private Number key;
private Node parent;
private Node leftChild;
private Node rightChild;
public Node(T data) {
assert null != data : "节点数据Null";
this.data = data;
this.key = data instanceof Number ? (Number) data : data.hashCode();
}
public Node insert(Node rootNode) {
if (null == rootNode) {
return this;
}
if (this.key.intValue() == rootNode.getKey().intValue()) {
throw new RuntimeException("排序树中不允许key值相等的存在");
}
if (this.key.intValue() < rootNode.getKey().intValue()) {
if (rootNode.getLeftChild() == null) {
rootNode.setLeftChild(this);
this.setParent(rootNode);
return this;
}
this.insert(rootNode.getLeftChild());
}
if (this.key.intValue() > rootNode.getKey().intValue()) {
if (rootNode.getRightChild() == null) {
rootNode.setRightChild(this);
this.setParent(rootNode);
return this;
}
this.insert(rootNode.getRightChild());
}
return this;
}
public T getData() {
return data;
}
public Node setData(T data) {
this.data = data;
return this;
}
public Number getKey() {
return key;
}
public Node setKey(Number key) {
this.key = key;
return this;
}
public int getHeight() {
return Math.max(null == leftChild ? 0 : leftChild.getHeight(), null == rightChild ? 0 : rightChild.getHeight()) + 1;
}
public int getBalance() {
return (null == leftChild ? 0 : leftChild.getHeight())-(null == rightChild ? 0 : rightChild.getHeight());
}
public Node getParent() {
return parent;
}
public Node setParent(Node parent) {
this.parent = parent;
return this;
}
public Node getLeftChild() {
return leftChild;
}
public Node setLeftChild(Node leftChild) {
this.leftChild = leftChild;
return this;
}
public Node getRightChild() {
return rightChild;
}
public Node setRightChild(Node rightChild) {
this.rightChild = rightChild;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Node<?> node = (Node<?>) o;
return data.equals(node.data);
}
@Override
public int hashCode() {
return Objects.hash(data, key, parent, leftChild, rightChild);
}
public void preTraversing() {
System.out.print(this.data);
System.out.print(" ");
if (this.getLeftChild() != null) {
this.getLeftChild().preTraversing();
}
if (this.getRightChild() != null) {
this.getRightChild().preTraversing();
}
}
public void midTraversing() {
if (this.getLeftChild() != null) {
this.getLeftChild().midTraversing();
}
System.out.print(this.data);
System.out.print(" ");
if (this.getRightChild() != null) {
this.getRightChild().midTraversing();
}
}
public void postTraversing() {
if (this.getLeftChild() != null) {
this.getLeftChild().postTraversing();
}
if (this.getRightChild() != null) {
this.getRightChild().postTraversing();
}
System.out.print(this.data);
System.out.print(" ");
}
}